Pipedash
Deployment

REST API

Reference for the pipedash-web REST API and WebSocket. Covers auth, every route by group and curl examples.

The pipedash-web server exposes every Pipedash operation under /api/v1 and streams events on /api/v1/ws. The web UI calls the same routes. This page lists all of them.

All paths below are relative to /api/v1. The router registers paths that end in / as written, so they keep the slash, for example /api/v1/providers/. Request and response bodies are JSON.

Authentication

The server compares the Authorization header with the current value of PIPEDASH_VAULT_PASSWORD. If the variable is not set, every request passes. If it is set, protected routes need this header:

Authorization: Bearer <vault-password>

The comparison runs in constant time. A missing or wrong header returns status 401. The server reads the variable on every request, so opening or closing the vault changes the rule at once.

These paths skip the check:

  • Outside the API: any path that does not start with /api/v1/, such as the embedded frontend.
  • Prefixes: /api/v1/health, /api/v1/setup and /api/v1/vault.
  • Exact paths: /api/v1/ws and /api/v1/plugins. The subpath /api/v1/plugins/metadata needs the header.

/api/v1/factory-reset needs the header like every other route.

Errors

Handled errors return a JSON body with code, message and an optional details.

StatuscodeCause
400BAD_REQUESTInvalid config or provider type
401UNAUTHORIZEDProvider authentication failed
404NOT_FOUNDUnknown provider or pipeline
409CONFLICTSetup already done
501NOT_SUPPORTEDThe provider does not support the action
503NOT_INITIALIZEDSetup is still required
500INTERNAL_ERRORAny other failure

A 401 from the auth check has no body.

Health and setup

Both groups skip authentication.

MethodPathPurpose
GET/healthServer status, version and provider count
GET/setup/statusConfig and setup state
POST/setup/configSaves the first config and starts services

POST /setup/config takes { "config": { ... }, "vault_password": "<optional>" }. It returns 409 when the instance is already configured.

Providers

MethodPathPurpose
GET/providers/Lists providers
POST/providers/Creates a provider
GET/providers/{id}Reads a provider config
PUT/providers/{id}Updates a provider
DELETE/providers/{id}Removes a provider
POST/providers/{id}/validateChecks the saved credentials
PUT/providers/{id}/refresh-intervalChanges the stored refresh interval
GET/providers/{id}/organizationsLists organizations
GET/providers/{id}/permissionsReads saved permissions
GET/providers/{id}/featuresReads feature availability
GET/providers/{id}/table-schemaReads the table schema
POST/providers/validateChecks supplied credentials
POST/providers/organizationsDiscovers organizations
POST/providers/permissions/checkChecks token permissions
POST/providers/previewPreviews discoverable pipelines
POST/providers/field-optionsLoads dynamic config choices

POST /providers/ takes these fields:

FieldTypeDefault
namestringRequired
provider_typestringRequired
tokenstringRequired
configobject of strings{}
refresh_intervalinteger60

PUT /providers/{id} takes the same body without provider_type.

curl -X POST http://localhost:8080/api/v1/providers/ \
  -H "Authorization: Bearer <vault-password>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "GitHub OSS",
    "provider_type": "github",
    "token": "<github-token>",
    "config": { "selected_items": "hcavarsan/pipedash" }
  }'
{
  "id": 1,
  "name": "GitHub OSS",
  "provider_type": "github",
  "config": { "selected_items": "hcavarsan/pipedash" },
  "refresh_interval": 60
}

The response never includes the token. The validate, organizations, permissions and field-options routes take provider_type and config. The preview route also takes org, search, page and page_size. See the provider pages for each config key.

Pipelines

MethodPathPurpose
GET/pipelines/Lists pipelines
GET/pipelines/cachedLists cached pipelines
GET/pipelines/freshFetches pipelines from the providers
GET/pipelines/lazyLists pipelines page by page
GET/pipelines/{id}/runsRun history
GET/pipelines/{id}/runs/{run_number}One run in detail
POST/pipelines/{id}/triggerStarts a run
POST/pipelines/{id}/runs/{run_number}/cancelCancels a run
GET/pipelines/{id}/workflow-paramsTrigger form parameters

The list routes take an optional provider_id query. /pipelines/lazy also takes page (default 1) and page_size (default 20). /pipelines/{id}/runs takes the same page and page_size.

POST /pipelines/{id}/trigger takes workflow_id (required) and inputs (optional JSON). The server reads the target from workflow_id and ignores the {id} in the path, so the pipeline ID goes in both places. The response holds run_id, a string the provider returns.

curl -X POST "http://localhost:8080/api/v1/pipelines/<pipeline-id>/trigger" \
  -H "Authorization: Bearer <vault-password>" \
  -H "Content-Type: application/json" \
  -d '{ "workflow_id": "<pipeline-id>", "inputs": { "ref": "main" } }'
{ "run_id": "<run-id>" }

GET /pipelines/{id}/workflow-params lists the inputs a pipeline accepts. See trigger and cancel for the UI flow.

Plugins

MethodPathPurpose
GET/plugins/Lists plugins (no auth)
GET/plugins/metadataPlugin metadata

Cache

MethodPathPurpose
GET/cache/statsCache statistics
DELETE/cache/run-history/{pipeline_id}Clears one history cache
DELETE/cache/run-historyClears all history caches
DELETE/cache/pipelinesClears the pipeline cache
DELETE/cache/workflow-paramsClears the parameter cache
DELETE/cache/Clears every cache

Metrics

MethodPathPurpose
GET/metrics/configReads the global metrics config
PUT/metrics/configUpdates it
GET/metrics/pipelines/{id}/configReads a pipeline metrics config
PUT/metrics/pipelines/{id}/configUpdates it
POST/metrics/pipelines/{id}/queryQueries raw metrics
POST/metrics/aggregatedQueries aggregated metrics
GET/metrics/storage/statsMetric storage statistics
POST/metrics/flushDeletes metrics

PUT /metrics/config takes enabled and default_retention_days. The pipeline route takes enabled and retention_days. POST /metrics/flush takes an optional pipeline_id. See metrics.

Preferences

MethodPathPurpose
GET/preferences/table/{provider_id}/{table_id}Reads table preferences
PUT/preferences/table/{provider_id}/{table_id}Saves table preferences
GET/preferences/table/{provider_id}/{table_id}/defaultReads the defaults

Refresh

MethodPathPurpose
GET/refresh/modeReads the refresh mode
PUT/refresh/modeSets the mode with { "mode": "<mode>" }
POST/refresh/allRefreshes all pipelines now

See refresh for the modes and intervals.

Storage

MethodPathPurpose
GET/storage/configReads the storage config
PUT/storage/configUpdates it
GET/storage/config/contentReads the TOML text
PUT/storage/config/contentSaves TOML from { "content": "..." }
POST/storage/config/analyzeAnalyzes a change from { "new_content": "..." }
GET/storage/pathsEffective file paths
POST/storage/validateValidates a storage config
POST/storage/test-connectionTests a storage connection
GET/storage/vault-password-statusReports whether the password variable is set
POST/storage/migration/planBuilds a migration plan
POST/storage/migration/executeRuns a migration

See storage backends for what a migration moves.

Vault

The vault routes skip authentication.

MethodPathPurpose
GET/vault/statusLock state and password source
POST/vault/unlockOpens the vault with a password
POST/vault/lockCloses the session

GET /vault/status returns is_unlocked, password_source (env_var, session or none), backend, requires_password and is_first_time.

POST /vault/unlock takes password and returns success and message.

curl -X POST http://localhost:8080/api/v1/vault/unlock \
  -H "Content-Type: application/json" \
  -d '{ "password": "<vault-password>" }'
{ "success": true, "message": "Vault unlocked successfully" }

A failed attempt still returns status 200, with "success": false and a message such as Invalid password or storage error: .... If the vault is already open, the message is Vault is already unlocked.

A successful call sets PIPEDASH_VAULT_PASSWORD in the server process, so later requests must send that password as the bearer token. POST /vault/lock removes the variable. Its message says a restart is needed to clear the token cache fully.

System

MethodPathPurpose
POST/factory-resetRemoves all providers and metrics

The response holds providers_removed, caches_cleared, tokens_cleared and metrics_cleared.

WebSocket

Live events stream on /api/v1/ws. When PIPEDASH_VAULT_PASSWORD is set, the first message from the client must be:

{ "type": "auth", "token": "<vault-password>" }

The server closes the socket if the first message is missing, is not valid JSON, has another type or carries a wrong token. The server sends no reply on success. Without a password there is no handshake. After that, every event arrives as a text frame with this envelope:

{ "type": "pipeline-status-changed", "payload": {} }

type is the event name and payload is the event data. The server ignores text frames that the client sends after the handshake. The event names are:

GroupEvents
Providersproviders-changed, provider-added, provider-updated, provider-removed, provider-status-updated
Pipelinespipelines-fetched, pipelines-fetch-error, pipelines-updated, pipeline-status-changed
Runsrun-triggered, run-cancelled
Refreshrefresh-error
Metricsmetrics-generated, metrics-global-config-changed, metrics-config-changed, metrics-flushed
Migrationmigration-progress, migration-complete
Cachepipeline-cache-invalidated, run-history-cache-invalidated
Vaultvault-unlocked