{"openapi":"3.1.0","info":{"title":"Paseo Hub Public API","version":"1.0.0","description":"Log in the CLI, list projects, validate and install configuration, dispatch manual runs, and enroll Paseo daemons."},"servers":[{"url":"/","description":"This Hub instance"}],"tags":[{"name":"CLI login"},{"name":"Projects"},{"name":"Configurations"},{"name":"Runs"},{"name":"Daemons"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Paseo organization credential","description":"An organization API key or durable CLI login credential. Each operation requires the scope shown on the operation."}},"schemas":{"CliAuthorization":{"type":"object","properties":{"deviceCode":{"type":"string"},"userCode":{"type":"string"},"verificationUri":{"type":"string","format":"uri"},"verificationUriComplete":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"interval":{"type":"integer","exclusiveMinimum":0}},"required":["deviceCode","userCode","verificationUri","verificationUriComplete","expiresAt","interval"],"additionalProperties":false},"StartCliAuthorizationRequest":{"type":"object","properties":{},"additionalProperties":false},"CliAuthorizationPoll":{"oneOf":[{"type":"object","properties":{"status":{"type":"string","enum":["authorized"]},"interval":{"type":"integer","exclusiveMinimum":0},"credential":{"type":"string","minLength":1},"organizationId":{"type":"string","minLength":1}},"required":["status","interval","credential","organizationId"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","enum":["pending","slow_down","denied","expired","disclosed"]},"interval":{"type":"integer","exclusiveMinimum":0}},"required":["status","interval"],"additionalProperties":false}]},"PollCliAuthorizationRequest":{"type":"object","properties":{"deviceCode":{"type":"string","minLength":32,"maxLength":200}},"required":["deviceCode"],"additionalProperties":false},"ProjectList":{"type":"object","properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}},"required":["projects"],"additionalProperties":false,"example":{"projects":[{"id":"84af3583-23ff-4fcc-9838-ed3262499be2","name":"Payments","slug":"payments"}]}},"Project":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"additionalProperties":false},"Problem":{"type":"object","properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer","minimum":400,"maximum":599},"detail":{"type":"string"},"code":{"type":"string"},"requestId":{"type":"string"},"issues":{"type":"array","items":{"$ref":"#/components/schemas/FieldIssue"}}},"required":["type","title","status","detail","code","requestId"],"additionalProperties":false,"example":{"type":"https://paseo.sh/problems/invalid-request","title":"Invalid request","status":400,"detail":"The request body contains invalid fields.","code":"invalid_request","requestId":"5e967c44-fc22-4f6d-8fc5-1bbff33121af","issues":[{"path":["projectSlug"],"message":"Required"}]}},"FieldIssue":{"type":"object","properties":{"path":{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"integer"}]}},"message":{"type":"string"}},"required":["path","message"],"additionalProperties":false,"example":{"path":["projectSlug"],"message":"Required"}},"ValidatedConfiguration":{"type":"object","properties":{"projectSlug":{"type":"string"},"valid":{"type":"boolean","enum":[true]}},"required":["projectSlug","valid"],"additionalProperties":false,"example":{"projectSlug":"payments","valid":true}},"InstallConfigurationRequest":{"type":"object","properties":{"projectSlug":{"type":"string","minLength":1,"maxLength":100},"yaml":{"type":"string","minLength":1,"maxLength":1000000},"partials":{"type":"array","items":{"$ref":"#/components/schemas/ConfigurationPartial"},"maxItems":100}},"required":["projectSlug","yaml"],"additionalProperties":false,"description":"Install YAML and, when prompt include references are used, exactly the referenced UTF-8 partial files. Partial paths are relative to .paseo/partials/; at most 100 files and 5,000,000 combined content bytes are accepted.","example":{"projectSlug":"payments","yaml":"project: acme/payments\nenvironments:\n  - name: runner\n    kind: daemon\n    daemon: build-server\n    cwd: /workspace\ntriggers:\n  - name: deploy\n    on: manual.run\n    max_runtime: 1h\n    steps:\n      - id: deploy\n        environment: runner\n        max_runtime: 30m\n        idle_timeout: 5m\n        agent: { provider: test }\n        prompt:\n          - include: docs/safety.md","partials":[{"path":"docs/safety.md","content":"Follow the safety checklist."}]}},"ConfigurationPartial":{"type":"object","properties":{"path":{"type":"string","minLength":1,"maxLength":512},"content":{"type":"string","maxLength":1000000}},"required":["path","content"],"additionalProperties":false,"description":"A UTF-8 prompt partial path relative to .paseo/partials/ and its exact text content.","example":{"path":"docs/safety.md","content":"Follow the safety checklist."}},"InstalledConfiguration":{"type":"object","properties":{"projectSlug":{"type":"string"},"versionId":{"type":"string","format":"uuid"},"version":{"type":"integer","exclusiveMinimum":0},"active":{"type":"boolean","enum":[true]}},"required":["projectSlug","versionId","version","active"],"additionalProperties":false,"example":{"projectSlug":"payments","versionId":"84af3583-23ff-4fcc-9838-ed3262499be2","version":4,"active":true}},"DispatchedManualRun":{"type":"object","properties":{"deliveryKey":{"type":"string"},"providerEventReceiptId":{"type":"string","format":"uuid"},"triggerRunId":{"type":"string","format":"uuid"},"configuredTriggerName":{"type":"string"},"workflowStatus":{"type":"string","enum":["running","succeeded","failed","timed_out"]}},"required":["deliveryKey","providerEventReceiptId","triggerRunId","configuredTriggerName","workflowStatus"],"additionalProperties":false,"example":{"deliveryKey":"deploy-2026-08-06","providerEventReceiptId":"845e9d26-7977-45e1-bc69-d80a7b55a9cc","triggerRunId":"f83dc934-02a0-4849-8de7-699110be24ed","configuredTriggerName":"deploy","workflowStatus":"running"}},"DispatchManualRunRequest":{"type":"object","properties":{"projectSlug":{"type":"string","minLength":1,"maxLength":100},"expectedVersionId":{"type":"string","format":"uuid"},"trigger":{"type":"string","minLength":1,"maxLength":200},"actor":{"type":"string","minLength":1,"maxLength":200},"deliveryKey":{"type":"string","minLength":1,"maxLength":200},"input":{}},"required":["projectSlug","trigger","actor","deliveryKey"],"additionalProperties":false,"example":{"projectSlug":"payments","trigger":"deploy","actor":"automation","deliveryKey":"deploy-2026-08-06","input":{"environment":"production"}}},"EnrollmentToken":{"type":"object","properties":{"token":{"type":"string","minLength":32},"expiresAt":{"type":"string","format":"date-time"}},"required":["token","expiresAt"],"additionalProperties":false,"example":{"token":"one-time-secret-returned-only-once","expiresAt":"2026-08-06T18:10:00.000Z"}}},"parameters":{}},"paths":{"/api/v1/cli-authorizations":{"post":{"operationId":"startCliAuthorization","summary":"Start CLI login","description":"Starts an anonymous, expiring browser authorization for the Paseo CLI.","tags":["CLI login"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartCliAuthorizationRequest"}}}},"responses":{"201":{"description":"The CLI login request was created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CliAuthorization"}}}},"429":{"description":"Too many active authorization requests."},"503":{"description":"Durable storage is unavailable."}}}},"/api/v1/cli-authorizations/poll":{"post":{"operationId":"pollCliAuthorization","summary":"Poll CLI login","description":"Polls an anonymous CLI login request. An approved credential is disclosed exactly once.","tags":["CLI login"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PollCliAuthorizationRequest"}}}},"responses":{"200":{"description":"The current authorization state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CliAuthorizationPoll"}}}},"503":{"description":"Durable storage is unavailable."}}}},"/api/v1/projects":{"get":{"operationId":"listProjects","summary":"List projects","description":"Lists active projects in the authenticated organization.","tags":["Projects"],"security":[{"bearerAuth":[]}],"x-required-scopes":["projects:read"],"responses":{"200":{"description":"The organization's active projects.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectList"}}}},"401":{"description":"The bearer credential is missing, malformed, or revoked.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}},"WWW-Authenticate":{"description":"Bearer authentication challenge.","schema":{"type":"string","example":"Bearer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The bearer credential lacks projects:read.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"The operation failed unexpectedly.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Hub authentication or storage is unavailable.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/configurations/validate":{"post":{"operationId":"validateConfiguration","summary":"Validate configuration","description":"Validates and resolves the same YAML, prompt-partial bundle, project, daemon, and provider resources as installation without recording or activating a revision.","tags":["Configurations"],"security":[{"bearerAuth":[]}],"x-required-scopes":["configuration:validate"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallConfigurationRequest"}}}},"responses":{"200":{"description":"The configuration is valid for the project.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidatedConfiguration"}}}},"400":{"description":"The JSON request is malformed or has invalid fields.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"The bearer credential is missing, malformed, or revoked.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}},"WWW-Authenticate":{"description":"Bearer authentication challenge.","schema":{"type":"string","example":"Bearer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The bearer credential lacks configuration:validate.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"The project does not exist in the credential's organization.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The YAML, supplied prompt partial bundle, or Hub configuration is invalid.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"The operation failed unexpectedly.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Hub authentication or storage is unavailable.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/configurations/install":{"post":{"operationId":"installConfiguration","summary":"Install and activate configuration","description":"Validates YAML, strips optional project deployment metadata, resolves explicitly supplied prompt partials, records a configuration revision, and atomically activates it.","tags":["Configurations"],"security":[{"bearerAuth":[]}],"x-required-scopes":["configuration:install"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallConfigurationRequest"}}}},"responses":{"201":{"description":"The new configuration revision is active.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledConfiguration"}}}},"400":{"description":"The JSON request is malformed or has invalid fields.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"The bearer credential is missing, malformed, or revoked.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}},"WWW-Authenticate":{"description":"Bearer authentication challenge.","schema":{"type":"string","example":"Bearer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The bearer credential lacks configuration:install.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"The project does not exist in the credential's organization.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The YAML, supplied prompt partial bundle, or Hub configuration is invalid.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"The operation failed unexpectedly.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Hub authentication or storage is unavailable.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/manual-runs":{"post":{"operationId":"dispatchManualRun","summary":"Dispatch a manual run","description":"Uses deliveryKey as caller-supplied request identity in the existing durable manual-event path.","tags":["Runs"],"security":[{"bearerAuth":[]}],"x-required-scopes":["runs:dispatch"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DispatchManualRunRequest"}}}},"responses":{"200":{"description":"The durable manual event resolved to a run.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DispatchedManualRun"}}}},"400":{"description":"The JSON request or trigger input is invalid.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"The bearer credential is missing, malformed, or revoked.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}},"WWW-Authenticate":{"description":"Bearer authentication challenge.","schema":{"type":"string","example":"Bearer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The bearer credential lacks runs:dispatch or the actor is forbidden.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"The project, configuration, or manual trigger does not exist.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The existing manual event path could not resolve a run.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"The operation failed unexpectedly.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Hub authentication or storage is unavailable.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/daemons/enrollment-tokens":{"post":{"operationId":"issueEnrollmentToken","summary":"Issue a daemon enrollment token","description":"Returns a short-lived, single-use token for enrolling one daemon.","tags":["Daemons"],"security":[{"bearerAuth":[]}],"x-required-scopes":["daemons:enroll"],"responses":{"201":{"description":"A short-lived enrollment token was issued.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrollmentToken"}}}},"401":{"description":"The bearer credential is missing, malformed, or revoked.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}},"WWW-Authenticate":{"description":"Bearer authentication challenge.","schema":{"type":"string","example":"Bearer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The bearer credential lacks daemons:enroll.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"The operation failed unexpectedly.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Hub authentication or storage is unavailable.","headers":{"X-Request-ID":{"description":"The accepted or generated request identifier.","schema":{"type":"string"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"webhooks":{}}