REST API
The console is built on a JSON REST API at https://zenavo.app/api. Anything you can do in the console, you can do with it.
Authentication
Send an API key as a bearer token:
sh
curl -H "Authorization: Bearer $ZENAVO_API_KEY" https://zenavo.app/api/auth/meRequests from a browser session also need the header X-Zenavo-Request: 1 on anything other than GET; requests with a bearer token do not.
Conventions
- Bodies are JSON. Times are Unix seconds.
- IDs are prefixed:
team_,srv_,proj_,job_,bak_,tok_. - Errors return a status code and
{"detail": …}. Validation errors (422) list each field. - Long operations (deploy, restart, backup) return a job:
{"id": "job_…"}. PollGET /api/jobs/{id}forstatus(queued,running,succeeded,failed),logand per-serviceprogress.
Endpoints
Account
| Method | Path | |
|---|---|---|
GET | /api/auth/me | The signed-in user and their teams |
PATCH | /api/account | Name and avatar |
GET POST | /api/account/tokens | List or create API keys (browser session only) |
DELETE | /api/account/tokens/{id} | Delete an API key |
GET | /api/account/sessions | Signed-in sessions |
Teams
| Method | Path | |
|---|---|---|
GET POST | /api/teams | List or create teams |
PATCH | /api/teams/{tid} | Rename |
GET | /api/teams/{tid}/members | Members |
PATCH DELETE | /api/teams/{tid}/members/{uid} | Change a role, remove a member |
GET POST | /api/teams/{tid}/invites | Invitations |
Servers
| Method | Path | |
|---|---|---|
GET | /api/servers?team_id= | List servers |
POST | /api/servers?team_id= | Add a server: {name, host, port, user, password | private_key} |
GET PATCH | /api/servers/{sid} | Read, rename |
POST | /api/servers/{sid}/bootstrap | Run setup again |
GET | /api/servers/{sid}/usage?hours= | CPU, memory and disk history |
GET | /api/servers/{sid}/system | Platform components |
GET | /api/servers/{sid}/ports | Port checks |
GET | /api/servers/{sid}/jobs | Setup and other jobs |
POST | /api/servers/{sid}/delete | Remove: {confirmation: "<server name>"} |
Projects
| Method | Path | |
|---|---|---|
GET | /api/projects?team_id= | List projects |
POST | /api/projects | Create: {team_id, server_id, manifest} |
GET | /api/projects/{pid} | Summary, services and status |
GET | /api/projects/{pid}/manifest | The full configuration, with variables |
PUT | /api/projects/{pid} | Save the configuration: {manifest, server_id, revision} |
POST | /api/projects/{pid}/deploy | Deploy all services (returns a job) |
POST | /api/projects/{pid}/rollback | {target_job} |
POST | /api/projects/{pid}/restart /stop | Restart or stop every service |
GET | /api/projects/{pid}/runtime | Live state of each service |
POST | /api/projects/{pid}/clone /transfer | Copy, or move to another team |
POST | /api/projects/{pid}/delete | {confirmation: "<project name>"} |
Services
| Method | Path | |
|---|---|---|
POST | /api/projects/{pid}/services/{name}/deploy | Deploy this service only; the others stay as deployed (returns a job) |
POST | /api/projects/{pid}/services/{name}/restart /suspend /resume | |
POST | /api/projects/{pid}/services/{name}/exec | Run a command in the container |
GET | /api/projects/{pid}/services/{name}/usage?hours= | CPU and memory history |
GET | /api/projects/{pid}/logs/{service} | Recent runtime logs |
GET | /api/projects/{pid}/logs/{service}/stream | Live runtime logs (Server-Sent Events) |
POST | /api/projects/{pid}/services/{name}/domains | Generate a domain |
DELETE | /api/projects/{pid}/domains/{domain} | Remove a generated domain |
Backups
| Method | Path | |
|---|---|---|
GET | /api/backups?project_id= | List backups |
POST | /api/projects/{pid}/backups | Back up a service: {service, engine} |
GET | /api/backups/{bid}/download | Download |
POST | /api/backups/{bid}/restore | Restore: {confirmation}, as typed in the console |
Git and GitHub
| Method | Path | |
|---|---|---|
POST | /api/git/refs | Branches and tags of a public repository: {url} |
POST | /api/git/plan | Build plan preview: {team_id, url, ref, context} |
GET | /api/github/repos?team_id= | Repositories the team's GitHub installations can read |
GET | /api/github/branches?team_id=&repo= | Branches of one of them |
Templates
| Method | Path | |
|---|---|---|
POST | /api/imports/preview | Check a Zeabur template or Zenavo export: {text, team_id, variables} |
POST | /api/imports/{did}/commit | Create the project: {server_id} |
Example: deploy and wait
sh
JOB=$(curl -s -X POST -H "Authorization: Bearer $ZENAVO_API_KEY" \
-H "Content-Type: application/json" -d '{}' \
https://zenavo.app/api/projects/$PROJECT/deploy | jq -r .id)
until curl -s -H "Authorization: Bearer $ZENAVO_API_KEY" https://zenavo.app/api/jobs/$JOB \
| jq -e '.status == "succeeded" or .status == "failed"' >/dev/null; do sleep 5; done