Documentation
Every endpoint, every CLI command, with copy-paste examples. All authenticated requests use Authorization: Bearer <token>. Base URL: https://voxenlabs.cloud.
#Quickstart
Three ways to use Voxen, in order of how fast you want to be productive.
#1. The dashboard (no install)
Sign up at voxenlabs.cloud/signup, hit "Create project," edit files in the browser IDE, click "Deploy." That's the whole loop.
#2. The CLI
curl -fsSL https://voxenlabs.cloud/install.sh | sh
vox login # paste a token from /dashboard/tokens
vox init my-app # writes voxen.toml
vox deploy # zip + upload + live#3. The HTTP API
Anything the CLI does is one HTTP request. Get a token from /dashboard/tokens, then:
# List your projects
curl https://voxenlabs.cloud/api/projects \
-H "Authorization: Bearer voxen_xxxxxxxxxx"#Authentication
Two auth modes. Browser sessions use a JWT in Authorization: Bearer <jwt> (or an httpOnly cookie); scripts use long-lived API tokens that start with voxen_.
#API tokens
Create at /dashboard/tokens, or with the CLI:
vox tokens create "ci-deploy" \
--scopes deploys:write,files:write \
--expires-in-days 90
# → voxen_a1b2c3d4...The token is shown once. Lose it, revoke and create a new one.
#Scopes
Scope a token to limit blast radius. A token with no scopes selected is unrestricted.
| Scope | Allows |
|---|---|
projects:read | List projects, view settings |
projects:write | Create / update / delete projects |
deploys:write | Trigger builds and publish |
files:read | Read draft files + manifests |
files:write | Push, pull, edit, delete files |
service:control | Start / stop / restart / scale |
db:read | List DBs + connection strings |
db:write | Create / scale / delete DBs, backups |
functions:read | Read function code + metadata |
functions:write | Create / update / delete functions |
billing:read | Balance, usage, transactions |
admin | All scopes |
#Two-factor auth
Optional TOTP on user accounts. Enable from Settings → Two-factor authentication. Browser logins prompt for a 6-digit code; backup codes are issued at enrollment and consumed on use. API tokens are not gated by 2FA — the gate is when you create the token in the dashboard.
#Projects
A project is a slug, a kind (STATIC · HOSTED · DOCKER · SERVICE), and resources.
/api/projectsscope: projects:readList your projects.
{ "projects": [{ "id": "cmp...", "name": "Astrid", "slug": "astrid", "kind": "HOSTED", "serviceStatus": "LIVE", ... }] }/api/projectsscope: projects:writeCreate a project.
{
"name": "Astrid",
"slug": "astrid", // 1-8 chars = premium tier, 9+ = free
"kind": "HOSTED",
"paymentMethod": "credits" // required only if slug is premium
}/api/projects/[id]scope: projects:read/api/projects/[id]scope: projects:writeUpdate settings, resources, scaling. All fields optional.
{
"name": "new name",
"customDomain": "astrid.dev",
"passwordHash": "raw-password", // hashed server-side
"notFoundPath": "/404.html",
"spaFallback": true,
"redirects": [{ "from": "/old", "to": "https://...", "status": 301 }],
"headers": [{ "path": "/*", "name": "X-Frame-Options", "value": "DENY" }],
"memoryMb": 1024, // 128 → 16384, hot-swap
"cpuMillicores": 1000, // 100 → 8000, hot-swap
"storageMb": 10240, // requires rebuild
"replicas": 3, // requires rebuild
"autoSleepMinutes": 15 // 0 = always on
}/api/projects/[id]scope: projects:write#Files & drafts
Edits land in a draft workspace. Nothing goes live until you publish.
/api/projects/[id]/files/manifestscope: files:readList every file in the draft with SHA-256 hashes. Powers vox pull / vox push diffing.
{ "files": [{ "path": "/index.html", "bytes": 4231, "sha256": "..." }] }/api/projects/[id]/files/content?path=/index.htmlscope: files:read/api/projects/[id]/files/content?path=/index.htmlscope: files:write{ "content": "<html>...</html>" }/api/projects/[id]/files/content?path=/old.htmlscope: files:write/api/projects/[id]/draftscope: deploys:writePublish or discard the draft.
{ "action": "publish" } // or "discard"#Deploys
For static projects you can also skip the draft and upload a zip directly.
/api/deploysscope: deploys:writeMultipart form: zip=<file.zip>, projectId=....
curl -F "zip=@./dist.zip" -F "projectId=cmp..." \
-H "Authorization: Bearer voxen_..." \
https://voxenlabs.cloud/api/deploys/api/projects/[id]/deploysscope: projects:read/api/projects/[id]/deploys/[did]scope: deploys:writeRoll back to a previous deploy.
/api/projects/[id]/deploys/[did]scope: deploys:writeArchive a deploy.
#Service control
For HOSTED / DOCKER / SERVICE projects.
/api/projects/[id]/service/controlscope: service:control{ "action": "start" | "stop" | "restart" }/api/projects/[id]/service/rebuildscope: service:controlForce-rebuild the active deploy without changing files.
/api/projects/[id]/service/logs?tail=Nscope: projects:read#Env vars
Encrypted server-side. Injected at container start.
/api/projects/[id]/env?reveal=1scope: projects:readreveal=1 decrypts values; without it, values come back as null.
/api/projects/[id]/envscope: projects:write{
"set": { "STRIPE_KEY": "sk_live_xxx", "NODE_ENV": "production" },
"unset": ["OLD_KEY"]
}Reserved (auto-injected): PORT, VOXEN_PROJECT, VOXEN_REPLICA.
#Scaling
Memory and CPU hot-swap on running containers. Disk, replicas, and env changes need a restart/rebuild.
All scaling lives on PATCH /api/projects/[id] — see the projects table above.
#Pricing formula
compute_cents_per_hour =
max(1,
ceil(memoryMb / 256) // 1¢ per 256 MB
+ ceil(cpuMillicores / 500) // 1¢ per 0.5 vCPU
+ floor(storageMb / 10240) // 1¢ per 10 GB disk
)
* replicas
# Example: 512 MB / 0.5 vCPU / 1 GB / 1 replica = 3¢/hr = $21.60/mo#Custom domains
- Set
customDomainvia PATCH on the project. - Add a CNAME pointing your domain at
<slug>.voxenlabs.cloud. - We auto-verify and issue Let's Encrypt TLS — usually within a minute.
Status flows: PENDING → VERIFYING → LIVE (or FAILED).
#Databases
Managed Postgres, MySQL, MariaDB, Redis.
/api/hosted-dbsscope: db:read/api/hosted-dbsscope: db:write{
"name": "app-prod",
"engine": "POSTGRES", // POSTGRES | MYSQL | MARIADB | REDIS
"paymentMethod": "credits"
}/api/hosted-dbs/[id]scope: db:readReturns { database, connectionString } if LIVE.
/api/hosted-dbs/[id]scope: db:write{
"name": "new-name",
"memoryMb": 2048, "cpuMillicores": 1000,
"storageMb": 51200, // only grow, requires restart
"cacheMb": 512, "maxConns": 100,
"backupSchedule": "daily", // or "off"
"backupRetentionDays": 14
}/api/hosted-dbs/[id]/controlscope: db:write{ "action": "start" | "stop" }/api/hosted-dbs/[id]scope: db:write#DB backups
/api/hosted-dbs/[id]/backupsscope: db:read/api/hosted-dbs/[id]/backupsscope: db:writeTrigger a manual snapshot. Returns { backupId, status: "RUNNING" }. Poll the list to watch it flip to READY.
Scheduled (daily) backups run from a cron at the top of each hour and prune past the retention window.
#Functions
Single-file Node handlers invoked over HTTP. 1¢ per call.
/api/functionsscope: functions:read/api/functionsscope: functions:write{
"name": "Webhook handler",
"slug": "webhook",
"code": "exports.handler = async (event) => ({ statusCode: 200, body: 'ok' });",
"timeoutMs": 5000,
"isPublic": true
}/api/functions/[id]scope: functions:read/api/functions/[id]scope: functions:write/api/functions/[id]scope: functions:write#Invoke
/api/fn/[slug]Any HTTP method. Public unless isPublic=false, in which case the token must own the function.
curl -X POST https://voxenlabs.cloud/api/fn/webhook \
-H "Content-Type: application/json" \
-d '{"event":"order.created"}'#Billing & usage
/api/credits?limit=Nscope: billing:readBalance + recent transactions.
{ "balanceCents": 1240, "transactions": [
{ "amountCents": -3, "reason": "compute:cmp...:hourly", "metadata": {...}, "createdAt": "..." }
]}/api/usagescope: billing:readLive burn rate + MTD breakdown + per-resource spend.
/api/billing/topupReturns a Stripe checkout URL for $1+ in credits.
{ "amountCents": 1000 } // → { "url": "https://checkout.stripe.com/..." }#Notifications & spend caps
/api/notifications/api/notifications{
"notifyEmail": true,
"lowBalanceCents": 500, // email when balance < $5
"softCapCents": 5000, // email when MTD > $50
"hardCapCents": 20000 // auto-stop services when MTD > $200
}Set any to null to disable that threshold. Hourly cron checks; alerts debounce on 12-hour windows.
#AI chat
/api/projects/[id]/ai/chatUI-message streaming response. Tools available to the model:
list_files,read_file,write_file,delete_file— edit the draftweb_search(query)— live web via Tavilyfetch_url(url)— pull arbitrary URLs (up to 50 KB)
Charged per token at inference cost + a thin margin.
#Errors
All errors are { "error": "human-readable message" } with an appropriate HTTP status.
| Status | Means |
|---|---|
400 | Bad request — validation failed |
401 | Missing or invalid token; for login, needsTotp: true if 2FA required |
402 | Insufficient credit balance |
403 | Token missing required scope, or non-owner |
404 | Resource not found or not yours |
500 | Something we did wrong — check status page |
#CLI reference
Install:
curl -fsSL https://voxenlabs.cloud/install.sh | sh#Projects
vox login # paste a token
vox init my-app --kind hosted # writes voxen.toml
vox projects ls
vox projects create my-app --slug my-app --kind hosted
vox projects info my-app
vox projects use my-app # set default in ~/.voxen/config.json
vox deploy # uses voxen.toml in cwd
vox publish # publish draft
vox status
vox open#Files
vox push # local → draft (sha256 diff)
vox pull # draft → local
vox discard # throw away unpublished changes#Service
vox scale --memory 2GB --cpu 1
vox scale --replicas 3 --sleep 15
vox scale --sleep off
vox restart | stop | start | rebuild
vox logs --tail 200
voxenv ls
voxenv set DATABASE_URL=postgres://...
voxenv unset OLD_KEY#Databases
vox db ls
vox db create app-prod --engine postgres
vox db info <id>
vox db connstr <id>
vox db psql <id> # spawns local psql with conn string
vox db backups ls <id>
vox db backups run <id>
vox db backups schedule <id> --schedule daily --retain 14#Functions, domains, tokens
vox fn ls | create | deploy <slug> <file.js> | invoke <slug> | rm
vox domains ls | add <host> --project <p> | rm
vox tokens create "ci" --scopes deploys:write --expires-in-days 30
vox tokens ls | rm <id>#Settings / redirects / headers
vox settings # show
vox settings name "New Name"
vox settings not-found /404.html
vox settings spa on
vox settings password "secret" # or "off"
vox redirects add /old https://new --status 301
vox headers add "/*" X-Frame-Options DENY#Deploys & logs
vox deploys ls
vox deploys rollback <deploy-id>
vox build-logs # latest
vox tail # follow live logs#Collaboration / GitHub
vox members add alice@x.com --role EDITOR
vox members role alice@x.com OWNER
vox members rm alice@x.com
vox github status
vox github link voxenlabs/my-app --branch main
vox github unlink#2FA & notifications
vox 2fa setup # walks through QR + verify
vox 2fa disable
vox notifications # show
vox notifications set --low-balance 5 --soft-cap 50 --hard-cap 200#Insights, slugs, branding
vox analytics --days 30
vox submissions # form submissions
vox slugs mine
vox slugs check axt
vox branding status
vox branding pay # one-time, removes footer#Files & storage
vox files ls
vox files cat /index.html
vox files put /index.html ./build/index.html
vox files rm /old.html
vox files rename /old /new
vox storage ls # buckets
vox storage put <bucket> key ./file
vox storage get <bucket> key > file#Starters & templates
vox starters ls
vox starters use nextjs-blog --name "My Blog"
vox templates deploy n8n --name "Automation"#AI
vox ai "add a contact form to /contact.html"
vox ai-apply <message-id> # accept proposal
vox ai-discard <message-id> # reject#Billing & Stripe Connect
vox balance
vox usage # full breakdown
vox topup 25
vox connect status # for taking payments on your sites
vox connect onboard#voxen.toml
project = "astrid"
kind = "hosted"
[deploy]
include = ["**/*"]
exclude = ["node_modules", ".git", ".next", "*.log", ".env*"]
[env]
NODE_ENV = "production"Run any command from anywhere under the directory containing voxen.toml and it picks up the project automatically.