API Reference
Vesta’s API server exposes a RESTful API for every platform operation — the CLI and web UI
are both built on it. All paths below are relative to /api/v1 unless noted.
Authentication
Most endpoints require a bearer token. Create one under API tokens, then:
curl -H "Authorization: Bearer <token>" https://<api-host>/api/v1/apps
Tokens carry scopes (read, write, deploy) and users carry roles (admin, developer,
viewer). Write endpoints reject the viewer role.
Unauthenticated endpoints
| Method | Path | Description |
|---|
GET | /healthz | Health check (outside /api/v1) |
GET | /setup/status | Whether first-run setup is complete |
POST | /setup | Create the first admin account |
POST | /auth/login | Login and receive a JWT |
GET | /auth/oauth/:provider | Start an OAuth login |
GET | /auth/forgot-password/status | Whether password reset is configured |
POST | /auth/forgot-password | Request a password reset |
POST | /auth/reset-password | Complete a password reset |
POST | /auth/accept-invite | Accept a team invitation |
POST | /webhooks/:provider | Inbound webhook (verified by signature) |
POST | /webhooks/:provider/:connectionId | Inbound webhook for a specific git connection |
Projects & environments
| Method | Path | Description |
|---|
GET | /projects | List projects |
POST | /projects | Create a project |
GET | /projects/:projectId | Get a project |
PUT | /projects/:projectId | Update a project |
DELETE | /projects/:projectId | Delete a project |
GET | /projects/:projectId/environments | List environments |
POST | /projects/:projectId/environments | Create an environment |
PUT | /projects/:projectId/environments/:env | Update an environment |
DELETE | /projects/:projectId/environments/:env | Delete an environment |
POST | /projects/:projectId/environments/:env/clone | Clone an environment |
GET | /projects/:projectId/members | List project members |
GET | /projects/:projectId/dependencies | App dependency graph |
Apps
Apps live inside a project, so they are created under the project and addressed by app ID
afterwards.
| Method | Path | Description |
|---|
GET | /apps | List all apps |
POST | /projects/:projectId/apps | Create an app |
GET | /projects/:projectId/apps | List apps in a project |
GET | /apps/:appId | Get app details |
PUT | /apps/:appId | Update an app |
DELETE | /apps/:appId | Delete an app |
POST | /apps/:appId/clone | Clone an app |
GET | /pod-sizes | Available pod size presets |
Deployments
| Method | Path | Description |
|---|
POST | /apps/:appId/deploy | Deploy an app |
POST | /apps/:appId/rollback | Roll back to a previous version |
GET | /apps/:appId/deployments | List deployments |
POST | /apps/:appId/restart | Restart pods |
POST | /apps/:appId/scale | Scale replicas |
POST | /apps/:appId/stop · /start | Stop or start an app |
POST | /apps/:appId/sleep · /wake | Sleep or wake an app |
GET | /projects/:projectId/scheduled-deployments | List scheduled deployments |
POST | /projects/:projectId/scheduled-deployments | Schedule a deployment |
Deploy request body — environment is required:
{
"environment": "production",
"tag": "v1.2.3",
"reason": "hotfix for #412",
"commitSHA": "7f3c9a1"
}
To deploy from git instead of a pre-built tag, send type: "git" with a git reference:
{
"environment": "production",
"type": "git",
"git": { "branch": "main" }
}
Builds
| Method | Path | Description |
|---|
POST | /apps/:appId/builds | Trigger a build |
GET | /apps/:appId/builds | List builds |
GET | /apps/:appId/builds/:buildId | Get a build |
GET | /apps/:appId/builds/:buildId/logs | Build logs |
POST | /apps/:appId/builds/:buildId/cancel | Cancel a build |
GET | /git/repos · /git/branches | Repos and branches available to the GitHub App |
Config, secrets & env vars
| Method | Path | Description |
|---|
GET | /apps/:appId/envs/:env/envvars | List non-secret env vars |
POST | /apps/:appId/envs/:env/envvars | Set env vars |
DELETE | /apps/:appId/envs/:env/envvars/:key | Delete an env var |
GET | /apps/:appId/envs/:env/secrets | List secret keys (values hidden) |
POST | /apps/:appId/envs/:env/secrets | Set a secret |
GET | /apps/:appId/envs/:env/secrets/reveal | Reveal secret values |
GET | /secrets | List all secrets (metadata) |
PUT · DELETE | /secrets/:secretId | Update or delete a secret |
GET · POST | /secrets/registry | Manage registry (image pull) secrets |
GET · POST | /projects/:projectId/shared-secrets | Project-scoped shared secrets |
POST · DELETE | /apps/:appId/shared-secrets | Bind or unbind a shared secret |
Observability & operations
| Method | Path | Description |
|---|
GET | /apps/:appId/logs | Stream logs (SSE) |
GET | /apps/:appId/logs/ws | Stream logs (WebSocket) |
GET | /apps/:appId/exec | Interactive shell into a pod (WebSocket) |
GET | /apps/:appId/metrics | CPU/memory metrics |
GET | /apps/:appId/metrics/prometheus | Prometheus metrics for the app |
GET | /apps/:appId/diagnostics | Why an app is unhealthy |
GET | /apps/:appId/files · /files/read | Browse and read files in a pod |
POST | /apps/:appId/files/write | Write a file in a pod |
GET | /apps/:appId/cronjobs/status | CronJob statuses |
POST | /apps/:appId/cronjobs/:name/trigger | Trigger a CronJob now |
GET · PUT | /apps/:appId/rate-limits | Ingress rate limits |
GET | /health/dashboard | Cluster-wide health dashboard |
Notifications & alerts
| Method | Path | Description |
|---|
GET · POST | /projects/:projectId/notifications | Manage notification channels |
PUT · DELETE | /projects/:projectId/notifications/:channelId | Update or delete a channel |
POST | /projects/:projectId/notifications/:channelId/test | Send a test notification |
GET | /projects/:projectId/notifications/history | Delivery history |
GET · POST | /projects/:projectId/alerts | Manage alert rules |
PUT · DELETE | /projects/:projectId/alerts/:ruleId | Update or delete an alert rule |
Add-ons
| Method | Path | Description |
|---|
GET · POST | /projects/:projectId/addons | List or create managed datastores |
DELETE | /projects/:projectId/addons/:name | Delete an add-on |
GET | /projects/:projectId/addons/:name/credentials | Connection details for an add-on |
POST | /apps/:appId/addons | Bind an add-on’s credentials into an app |
DELETE | /apps/:appId/addons/:name | Remove a binding |
Cost & quotas
| Method | Path | Description |
|---|
GET | /projects/:projectId/costs | Project cost, grouped by app or environment |
GET | /apps/:appId/costs | One app’s cost |
GET | /projects/:projectId/environments/:env/quota | Configured quota, plus what is committed and used |
PUT | /projects/:projectId/environments/:env/quota | Set an environment’s quota |
Cost responses accept ?window= (24h, 7d, 30d, 90d, or a Go duration) and
?groupBy=app|environment. Every response reports the rate card it used and whether those
rates are the built-in estimate, so a figure can be checked rather than taken on trust.
Quota responses report committed — what the environment’s apps add up to at their
autoscaling maximum — alongside wouldExceed, which says whether enforcing the configured
quota would already refuse work.
Git connections & repositories
| Method | Path | Description |
|---|
GET · POST | /settings/git-connections | List or add a GitHub, GitLab or Bitbucket connection |
DELETE | /settings/git-connections/:connectionId | Remove a connection |
GET | /git/repos | Repositories across every connection |
GET | /git/branches | Branches for a repository |
Registry credentials
| Method | Path | Description |
|---|
GET · POST | /secrets/registry | List or create registry credentials |
DELETE | /secrets/registry/:name | Delete a credential |
GET | /secrets/registry/:name/repositories | Repositories the credential can see |
GET | /secrets/registry/:name/tags | Tags for a repository (?repository=) |
POST | /secrets/registry/:name/test | Check the credential against its registry |
Creating a credential accepts scope (global or project) and, for a project-scoped one,
project. Only an administrator can create a global credential. A credential you may not use
is absent from the listing and returns 404 rather than 403 when addressed directly.
| Method | Path | Description |
|---|
GET | /settings/security | Pod hardening profile, network isolation, default secret scope |
PUT | /settings/security | Set the platform security posture (admin) |
GET · PUT | /settings/rbac | Per-project role enforcement |
GET | /users/me/permissions | What the caller may do, per project and environment |
GET /settings/security is readable by any authenticated user; writing it requires an
administrator. Under the restricted profile an app runs as a non-root user with a read-only
filesystem, so a developer who cannot see the profile has no way to explain their own app’s
failure to start.
Its observed field reports, per environment, whether network policies are actually being
enforced — which is a different question from whether isolation is turned on, because
NetworkPolicy is enforced by the cluster’s network plugin rather than by Kubernetes.
Users, teams & audit
| Method | Path | Description |
|---|
GET | /users/me | Current user |
PUT | /users/me · /users/me/password | Update profile or password |
GET | /users | List users (admin) |
POST | /auth/register | Create a user (admin) |
GET · POST | /teams | List or create teams |
GET · PUT · DELETE | /teams/:teamId | Manage a team |
POST · DELETE | /teams/:teamId/members | Add or remove team members |
GET · POST | /auth/tokens | List or create API tokens |
DELETE | /auth/tokens/:id | Revoke an API token |
GET | /audit-logs | Audit log |
GET | /activity | Activity feed |
GET | /webhook-deliveries | Webhook delivery log (admin) |
GET | /templates | App templates |
POST | /templates/:id/deploy | Deploy from a template |