API Reference Complete REST API reference for all Vardo endpoints -- authentication, resources, webhooks and error handling.
All API endpoints (except /api/health and /api/v1/github/webhook) require authentication. Vardo supports two authentication methods:
The web dashboard uses session-based authentication managed by Better Auth. Sessions are stored in PostgreSQL, expire after 7 days (configurable) and are refreshed every 24 hours. When using the API from a browser context, the session cookie is sent automatically.
Create API tokens from User Settings > API Tokens in the dashboard. Tokens use a vardo_ prefix, are stored as SHA-256 hashes and displayed only once at creation time. Tokens are scoped to a specific organization and user.
curl -s https://vardo.example.com/api/v1/organizations/{orgId}/apps \
-H "Authorization: Bearer vardo_<your-token>"
When authenticating via token, the org context is derived from the token itself -- no cookie is required. This makes tokens suitable for CI/CD pipelines, scripts and API integrations.
All versioned API endpoints follow the pattern:
/api/v1/organizations/{orgId}/...
The orgId is the organization ID (not the slug). You can find it from the organization list endpoint or from the dashboard URL.
Vardo uses a Redis-backed sliding window rate limiter applied per route via the withRateLimit wrapper.
Tier Limit Window Identity Used for auth5 req 60s IP / token hash Login, signup, magic link, passkey public30 req 60s IP / token hash Webhooks, mesh join mutation60 req 60s User ID / token hash Create, update, delete operations read120 req 60s User ID / token hash List, get, stream admin30 req 60s User ID / token hash Admin API endpoints critical10 req 60s User ID / token hash Deploy, rollback
When rate-limited, the API returns HTTP 429 with a Retry-After header indicating seconds until the oldest request in the window ages out. If Redis is unavailable, requests are allowed through -- a Redis outage won't take down the API.
All error responses follow a consistent shape:
{
"error" : "Human-readable error message"
}
Code Meaning 400 Bad request (validation error) 401 Unauthorized (not authenticated) 403 Forbidden (no access to this organization) 404 Not found 409 Conflict (e.g. duplicate name) 429 Too many requests (rate limited) 500 Internal server error
Method Path Auth Description GET /api/healthNone Basic health check GET /api/health/systemNone System-level health GET /api/v1/admin/healthAdmin Detailed health with service status, runtime info, auth methods and feature flags
Method Path Description GET /api/v1/organizations/{orgId}Get organization details PATCH /api/v1/organizations/{orgId}Update organization DELETE /api/v1/organizations/{orgId}Delete organization
Method Path Description GET /api/v1/organizations/{orgId}/membersList organization members POST /api/v1/organizations/{orgId}/membersAdd a member PATCH /api/v1/organizations/{orgId}/members/{userId}Update a member's role DELETE /api/v1/organizations/{orgId}/members/{userId}Remove a member
Method Path Description GET /api/v1/organizations/{orgId}/invitationsList invitations POST /api/v1/organizations/{orgId}/invitationsInvite a user to the org DELETE /api/v1/organizations/{orgId}/invitations/{invitationId}Cancel an invitation POST /api/v1/invitations/acceptAccept an invitation (token-verified)
Method Path Description GET /api/v1/organizations/{orgId}/projectsList all projects POST /api/v1/organizations/{orgId}/projectsCreate a project GET /api/v1/organizations/{orgId}/projects/{projectId}Get project details PATCH /api/v1/organizations/{orgId}/projects/{projectId}Update a project DELETE /api/v1/organizations/{orgId}/projects/{projectId}Delete a project
Method Path Description GET /api/v1/organizations/{orgId}/projects/{projectId}/environmentsList project environments POST /api/v1/organizations/{orgId}/projects/{projectId}/environmentsCreate a project environment
Method Path Description GET /api/v1/organizations/{orgId}/projects/{projectId}/statsAggregate stats for a project GET /api/v1/organizations/{orgId}/projects/{projectId}/stats/streamLive project stats (SSE) GET /api/v1/organizations/{orgId}/projects/{projectId}/stats/historyHistorical project stats
Method Path Description GET /api/v1/organizations/{orgId}/appsList all apps POST /api/v1/organizations/{orgId}/appsCreate an app POST /api/v1/organizations/{orgId}/apps/sortUpdate app sort order GET /api/v1/organizations/{orgId}/apps/{appId}Get app details PATCH /api/v1/organizations/{orgId}/apps/{appId}Update an app DELETE /api/v1/organizations/{orgId}/apps/{appId}Delete an app
{
"displayName" : "My App" ,
"name" : "my-app" ,
"description" : "Optional description" ,
"source" : "git" ,
"deployType" : "dockerfile" ,
"gitUrl" : "https://github.com/user/repo" ,
"gitBranch" : "main" ,
"containerPort" : 3000 ,
"autoDeploy" : true ,
"generateDomain" : true ,
"projectId" : "optional-project-id"
}
source -- "git" or "direct"
deployType -- "compose", "dockerfile", "image", "static", "nixpacks" or "railpack"
Additional fields depending on deploy type:
image : imageName (required)
compose : composeContent (inline YAML)
git sources : gitUrl, gitBranch, rootDirectory
resource limits : cpuLimit (cores, max 64), memoryLimit (MB, 64-65536), diskWriteAlertThreshold (bytes)
volumes : persistentVolumes array of { name, mountPath }
ports : exposedPorts array of { internal, external?, protocol?, description? }
connection info : connectionInfo array of { label, value, copyRef? }
Method Path Description POST /api/v1/organizations/{orgId}/apps/{appId}/deployTrigger a deployment (returns SSE stream) GET /api/v1/organizations/{orgId}/apps/{appId}/deploy/streamStream deployment logs (SSE) POST /api/v1/organizations/{orgId}/apps/{appId}/stopStop an app POST /api/v1/organizations/{orgId}/apps/{appId}/restartRestart an app POST /api/v1/organizations/{orgId}/apps/{appId}/rollbackRoll back to a previous deployment
{
"environmentId" : "env_abc123" ,
"groupEnvironmentId" : "genv_abc123" ,
"deployAll" : true
}
Omit the body or send {} to deploy to the default (production) environment.
Set deployAll: true to trigger a project-wide deploy of all apps in the project.
The response is a Server-Sent Events stream with log, stage, tier and done events.
Method Path Description GET /api/v1/organizations/{orgId}/apps/{appId}/branchesList branches for the app's connected repository
Method Path Description GET /api/v1/organizations/{orgId}/apps/{appId}/env-varsList app env vars POST /api/v1/organizations/{orgId}/apps/{appId}/env-varsSet app env vars GET /api/v1/organizations/{orgId}/env-varsList org-level shared env vars POST /api/v1/organizations/{orgId}/env-varsSet org-level shared env vars
Method Path Description GET /api/v1/organizations/{orgId}/apps/{appId}/domainsList app domains POST /api/v1/organizations/{orgId}/apps/{appId}/domainsAdd a domain DELETE /api/v1/organizations/{orgId}/apps/{appId}/domainsRemove a domain POST /api/v1/organizations/{orgId}/apps/{appId}/domains/primarySet the primary domain GET /api/v1/organizations/{orgId}/apps/{appId}/domains/healthCheck domain health GET /api/v1/organizations/{orgId}/domainsList all org domains POST /api/v1/organizations/{orgId}/domainsAdd an org domain
Method Path Description GET /api/v1/organizations/{orgId}/apps/{appId}/environmentsList app environments POST /api/v1/organizations/{orgId}/apps/{appId}/environmentsCreate an environment GET /api/v1/organizations/{orgId}/apps/{appId}/environments/{envId}Get environment details PATCH /api/v1/organizations/{orgId}/apps/{appId}/environments/{envId}Update an environment DELETE /api/v1/organizations/{orgId}/apps/{appId}/environments/{envId}Delete an environment POST /api/v1/organizations/{orgId}/apps/{appId}/environments/{envId}/cloneClone an environment
Environment types: "production", "staging", "preview".
Method Path Description GET /api/v1/organizations/{orgId}/apps/{appId}/statsCurrent container stats (CPU, memory, network) GET /api/v1/organizations/{orgId}/apps/{appId}/stats/streamLive stats stream (SSE) GET /api/v1/organizations/{orgId}/apps/{appId}/stats/historyHistorical stats GET /api/v1/organizations/{orgId}/apps/{appId}/logsQuery logs (Loki with Docker fallback) GET /api/v1/organizations/{orgId}/apps/{appId}/logs/streamLive log stream (SSE) GET /api/v1/organizations/{orgId}/apps/{appId}/containersList containers for an app GET /api/v1/organizations/{orgId}/apps/{appId}/eventsApp events (SSE -- deploy:complete, etc.) GET /api/v1/organizations/{orgId}/apps/{appId}/volumesList volumes GET /api/v1/organizations/{orgId}/apps/{appId}/terminalWebSocket terminal access
Method Path Description GET /api/v1/organizations/{orgId}/statsAggregate stats for the org GET /api/v1/organizations/{orgId}/stats/streamLive org stats (SSE) GET /api/v1/organizations/{orgId}/stats/businessBusiness metrics
Method Path Description GET /api/v1/organizations/{orgId}/backupsList backup overview GET /api/v1/organizations/{orgId}/backups/targetsList backup targets POST /api/v1/organizations/{orgId}/backups/targetsCreate a backup target GET /api/v1/organizations/{orgId}/backups/targets/{targetId}Get backup target details PATCH /api/v1/organizations/{orgId}/backups/targets/{targetId}Update a backup target DELETE /api/v1/organizations/{orgId}/backups/targets/{targetId}Delete a backup target GET /api/v1/organizations/{orgId}/backups/jobs/{jobId}Get backup job details PATCH /api/v1/organizations/{orgId}/backups/jobs/{jobId}Update a backup job POST /api/v1/organizations/{orgId}/backups/jobs/{jobId}/runTrigger a backup job manually GET /api/v1/organizations/{orgId}/backups/history/{backupId}/downloadDownload a backup archive POST /api/v1/organizations/{orgId}/backups/history/{backupId}/restoreRestore from a backup
Storage backends: S3, Cloudflare R2, Backblaze B2, SSH/SFTP, local filesystem.
Backup strategies are per-volume: tar for file volumes, pg_dump for Postgres.
Method Path Description GET /api/v1/organizations/{orgId}/apps/{appId}/cronList cron jobs for an app POST /api/v1/organizations/{orgId}/apps/{appId}/cronCreate a cron job
Cron job types: "command" (runs inside the container) or "url" (HTTP request).
Method Path Description GET /api/v1/organizations/{orgId}/tagsList tags POST /api/v1/organizations/{orgId}/tagsCreate a tag GET /api/v1/organizations/{orgId}/apps/{appId}/tagsList tags for an app POST /api/v1/organizations/{orgId}/apps/{appId}/tagsAssign a tag to an app DELETE /api/v1/organizations/{orgId}/apps/{appId}/tagsRemove a tag from an app
Method Path Description POST /api/v1/organizations/{orgId}/apps/{appId}/transferInitiate an app transfer GET /api/v1/organizations/{orgId}/transfersList incoming/outgoing transfers PATCH /api/v1/organizations/{orgId}/transfers/{transferId}Accept or reject a transfer
Method Path Description GET /api/v1/organizations/{orgId}/deploy-keysList deploy keys POST /api/v1/organizations/{orgId}/deploy-keysCreate a deploy key
Method Path Description GET /api/v1/organizations/{orgId}/tokensList API tokens POST /api/v1/organizations/{orgId}/tokensCreate a new token DELETE /api/v1/organizations/{orgId}/tokensDelete a token
Method Path Description GET /api/v1/organizations/{orgId}/notificationsList notification channels POST /api/v1/organizations/{orgId}/notificationsCreate a notification channel PATCH /api/v1/organizations/{orgId}/notifications/{channelId}Update a channel DELETE /api/v1/organizations/{orgId}/notifications/{channelId}Delete a channel GET /api/v1/organizations/{orgId}/notifications/streamReal-time notification stream (SSE)
Channel types: email (SMTP, Mailpace, Resend, Postmark), webhook (HTTP POST) and Slack (via webhook URL).
Method Path Description GET /api/v1/organizations/{orgId}/digestGet digest settings PATCH /api/v1/organizations/{orgId}/digestUpdate digest settings
Method Path Description GET /api/v1/organizations/{orgId}/activitiesList activity entries
Method Path Description GET /api/v1/organizations/{orgId}/searchSearch apps, projects and shared variables
Method Path Auth Description GET /api/v1/github/installationsSession List connected GitHub App installations GET /api/v1/github/reposSession List repositories (?installationId=...) POST /api/v1/github/reposSession Create a repo via GitHub App GET /api/v1/github/branchesSession List branches for a repository GET /api/v1/github/env-scanSession Scan a repo for environment variable usage POST /api/v1/github/connectSession Initiate GitHub App connection GET /api/v1/github/callbackNone OAuth callback handler POST /api/v1/github/webhookNone GitHub webhook receiver (signature-verified)
Method Path Description GET /api/v1/templatesList available app templates
Method Path Description GET /api/v1/dns-checkCheck DNS resolution for a domain
Method Path Description GET /api/v1/system/alertsList active system alerts
All admin endpoints require isAppAdmin on the authenticated user.
Method Path Description GET /api/v1/admin/overviewSystem overview -- user/app/deployment/template counts with sparklines, resource usage GET /api/v1/admin/healthService health, runtime info (Next.js version, Node version, uptime, memory), auth methods and feature flags GET /api/v1/admin/statsAdmin-level system stats GET /api/v1/admin/stats/streamLive admin stats (SSE)
Method Path Description GET /api/v1/admin/usersList all users GET /api/v1/admin/organizationsList all organizations GET /api/v1/admin/backup-targetsList all backup targets (system-wide) GET /api/v1/admin/backupsList all backups (system-wide) POST /api/v1/admin/docker-prunePrune unused Docker resources POST /api/v1/admin/dns-checkDNS check (admin context) GET /api/v1/admin/config/exportExport current config as vardo.yml + vardo.secrets.yml POST /api/v1/admin/config/importImport a vardo.yml config into system settings
These endpoints are only available when the mesh feature flag is enabled.
Method Path Description GET /api/v1/admin/mesh/peersList connected mesh peers POST /api/v1/admin/mesh/joinJoin a mesh network POST /api/v1/admin/mesh/inviteGenerate an invite token for a new peer POST /api/v1/admin/mesh/cloneClone an app from another instance POST /api/v1/admin/mesh/promotePromote an app to another instance POST /api/v1/admin/mesh/pullPull an app's config/volumes from another instance
These are called instance-to-instance over WireGuard tunnels -- not by end users.
Method Path Description POST /api/v1/mesh/joinAccept a join request from another instance POST /api/v1/mesh/heartbeatPeer heartbeat POST /api/v1/mesh/syncSync state with a peer POST /api/v1/mesh/cloneReceive a cloned app POST /api/v1/mesh/promoteReceive a promoted app POST /api/v1/mesh/pullRespond to a pull request
Vardo exposes a Model Context Protocol server for AI agent integration at /api/mcp. Authenticate with a Bearer token (API token).
Method Path Description POST /api/mcpMCP JSON-RPC endpoint (stateless, fresh server per request)
Available MCP tools (read-only):
Tool Description list-appsList all apps in the org get-app-statusGet status and details for a specific app get-app-logsGet recent logs for a specific app list-projectsList all projects in the org
Vardo receives GitHub webhooks at /api/v1/github/webhook. The webhook secret is verified using HMAC-SHA256 (x-hub-signature-256 header).
push -- Triggers auto-deploy for apps that match the repository URL and branch with autoDeploy enabled.
{
"ok" : true ,
"deployments" : [
{ "app" : "my-app" , "deploymentId" : "abc123" , "success" : true }
]
}
pull_request -- Creates or destroys preview environments.
opened, reopened, synchronize -- Creates a preview project environment for the matching project, deploys all apps and posts preview URLs as a PR comment.
closed -- Destroys the preview environment and tears down all containers.
{
"ok" : true ,
"preview" : {
"groupEnvironmentId" : "genv_abc123" ,
"domains" : [
{ "appName" : "web" , "domain" : "pr-42-web.example.com" }
],
"deployed" : true
}
}
All other event types are acknowledged with {"ok": true, "skipped": "<event-type>"}.
These endpoints are used during initial setup only and don't require authentication (the setup wizard runs before any user exists).
Method Path Description GET /api/setup/statusCheck if setup is needed GET /api/setup/progressGet setup wizard progress POST /api/setup/authConfigure auth settings POST /api/setup/backupConfigure backup storage POST /api/setup/emailConfigure email provider POST /api/setup/feature-flagsSet initial feature flags POST /api/setup/generalSet general settings POST /api/setup/githubConfigure GitHub App POST /api/setup/servicesConfigure infrastructure services POST /api/setup/sslConfigure SSL/TLS