ReferenceAPI reference

API reference

Everything the dashboard does goes through the DevLyft public API. You can call it too, with an API key, from scripts and CI.

Base URL#

Base URL
https://api.devlyft.io/v1

Routes are resource-first, such as /v1/projects/{project_id}/builds, with no per-service prefix. Request and response bodies are JSON.

Authentication#

Send an API key as a bearer token on every request.

Request
curl https://api.devlyft.io/v1/organizations \
  -H "Authorization: Bearer $DEVLYFT_TOKEN"

Create an API key#

  1. Open API Keys

    SettingsAPI Keys.

  2. Choose the scope

    Personal keys act as you. Organisation keys (the tab with your organisation's name) belong to the organisation. Creating or viewing organisation keys needs the Admin or Manager role.

  3. Name it and copy the token

    Give it a name such as CI/CD pipeline. Copy your new token now — it won't be shown again. Store it in your CI's secret store.

The key list shows when each key was last used and when it expires, if it has an expiry. Choose Revoke to disable a key. Revoked keys are marked Revoked.

Errors#

Errors use RFC 7807 problem details (application/problem+json).

Error response
{
  "title": "Forbidden",
  "status": 403,
  "detail": "…",
  "code": "…"
}

Show detail to people, and branch on status and code. A 204 response has no body.

Endpoints#

These are the endpoints the dashboard uses today.

AreaMethod and path
Users and keysGET /users · PUT /users/{user_id} · GET /users/{user_id}/memberships · GET|POST /users/{user_id}/tokens · DELETE /tokens/{token_id} · GET|POST /organizations/{org_id}/tokens
Organisations and membersGET|POST /organizations · PUT|DELETE /organizations/{org_id} · GET|POST /organizations/{org_id}/memberships · PUT|DELETE /organizations/{org_id}/memberships/{user_id}
ProjectsGET|POST /organizations/{org_id}/projects · PUT|DELETE /projects/{project_id}
EnvironmentsGET|POST /projects/{project_id}/environments · PUT|DELETE /environments/{environment_id}
SecretsGET /projects/{project_id}/environments/{environment_id}/secrets (keys only) · POST|DELETE …/secrets/{name}
BuildsGET|POST /projects/{project_id}/builds · PUT|DELETE /builds/{build_id}
DeploysGET|POST /projects/{project_id}/environments/{environment_id}/deploys · PUT|DELETE /deploys/{deploy_id}
DomainsGET|POST /organizations/{org_id}/domains · POST /organizations/{org_id}/domains/{domain}/verify · DELETE /organizations/{org_id}/domains/{domain}
RoutesGET|POST /deploys/{deploy_id}/routes · DELETE /deploys/{deploy_id}/routes/{route_id}
CatalogGET /locations · GET /instance-types
BillingGET /organizations/{org_id}/billing · POST /organizations/{org_id}/billing/setup · POST …/billing/setup/confirm
Nodes and podsGET /nodes · GET /projects/{project_id}/nodes · GET /projects/{project_id}/pods
LogsGET /deploys/{deploy_id}/logs · WebSocket /deploys/{deploy_id}/logs/stream
MetricsGET /metric-types · GET /metric-types/nodes · GET /deploys/{deploy_id}/metrics · GET /pods/{pod}/metrics · GET /nodes/{node_id}/metrics · GET /organizations/{org_id}/metrics

Paths are relative to /v1.

Examples#

Create a build
curl -X POST https://api.devlyft.io/v1/projects/$PROJECT_ID/builds \
  -H "Authorization: Bearer $DEVLYFT_TOKEN" -H "Content-Type: application/json" \
  -d '{"name":"api","image":"ghcr.io/acme/api","tag":"1.4.2","container_port":8080,"cpu_request":"0.5","memory_request":"512Mi"}'
Point a deploy at a new build
curl -X PUT https://api.devlyft.io/v1/deploys/$DEPLOY_ID \
  -H "Authorization: Bearer $DEVLYFT_TOKEN" -H "Content-Type: application/json" \
  -d '{"build_id":"'$BUILD_ID'","name":"api","location_id":"'$LOCATION'","replicas":2,"tenancy_type":"INHERIT","expose":true,"env":[{"kind":"env","key":"LOG_LEVEL","value":"info"},{"kind":"secret","key":"DATABASE_URL"}]}'

PUT replaces the deploy's configuration, so send every field you want to keep, including env and the autoscaling fields (enable_hpa, hpa_min_replicas, hpa_max_replicas, hpa_target_cpu) if they're set. Environment entries use kind: "env" with a value, or kind: "secret" with just the key.

Authenticating the logs stream#

Browsers can't set headers on a WebSocket handshake, so the logs stream takes the token as the subprotocol pair ["bearer", "<token>"].

JavaScript
new WebSocket(`wss://api.devlyft.io/v1/deploys/${deployId}/logs/stream`, ['bearer', token]);