Base URL: https://api.litevps.dev/api · openapi.json
POST /api/auth/login to obtain a JWT for all programmatic access.
curl -s -X POST https://api.litevps.dev/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"agent@example.com","password":"s3cr3t"}' \
| jq -r .token
TOKEN="eyJ..."
curl -s -X POST /api/vps \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"my-vm","plan_id":"<plan-id>"}' \
| jq '{id:.id, state:.state}'
VPS_ID="<id from step 2>"
while true; do
STATE=$(curl -s /api/vps/$VPS_ID \
-H "Authorization: Bearer $TOKEN" | jq -r .state)
echo "state: $STATE"
[ "$STATE" = "running" ] && break
sleep 5
done
curl -s -X POST /api/vps/$VPS_ID/exec \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"command":"uname -a"}' \
| jq '{stdout,stderr,exit_code,duration_ms}'
All protected endpoints require one of:
Authorization: Bearer <jwt> obtained from /api/auth/loginAuthorization: Bearer vtk_<token> created via POST /api/tokensX-Balance-Remaining: <float> showing the current USD account balance to 4 decimal places.
When balance is insufficient the API returns HTTP 402:
{
"error": "insufficient balance",
"balance": 0.0420,
"required": 0.1667
}
cf-turnstile-response · rate-limited 10 req/min per IP# Body fields: email, password, cf-turnstile-response (required)
# Obtain a CAPTCHA token from the portal — direct curl registration is blocked.
# → 400 "CAPTCHA verification failed" if token is missing or invalid
curl -X POST /api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"password123"}'
# → {"token":"eyJ..."}
curl /api/me -H "Authorization: Bearer $TOKEN"
# → {"id":"...","email":"you@example.com","balance":10.5000}
plan_id when creating a VPS.curl /api/pricing
# → [{"id":"...","name":"Nano","vcpu":1,"memory_mb":512,"disk_gb":10,"price_hourly":0.0042}]
GET /api/vps/:id until state = "running".curl -X POST /api/vps \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"name": "web-01",
"plan_id": "plan-uuid",
"ssh_key_ids": ["key-uuid"]
}'
| Field | Type | Notes |
|---|---|---|
| name | string | required hostname for the VM |
| plan_id | string | required UUID from GET /api/pricing |
| ssh_key_ids | []string | optional SSH keys to inject at cloud-init |
state is one of: creating, running, stopped, error./restart to reboot.{"name":"snap-name"}.GET /.well-known/agent.json.
path is required (e.g. ?path=/root/script.sh).curl -X PUT "/api/vps/$VPS_ID/files?path=/root/hello.txt" \
-H "Authorization: Bearer $TOKEN" \
--data-binary @hello.txt
path is required.curl "/api/vps/$VPS_ID/files?path=/etc/hostname" \
-H "Authorization: Bearer $TOKEN"
"background":true to get an async job ID and poll for completion. All calls are audit-logged.
"background":true) returns a job ID.# Synchronous
curl -X POST /api/vps/$VPS_ID/exec \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"command":"df -h /","timeout_seconds":30}'
# → {"stdout":"Filesystem ...","stderr":"","exit_code":0,"duration_ms":142}
# Asynchronous
curl -X POST /api/vps/$VPS_ID/exec \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"command":"apt-get update -y","timeout_seconds":300,"background":true}'
# → {"job_id":"...","status":"pending","timeout_seconds":300}
| Field | Type | Notes |
|---|---|---|
| command | string | required shell command to run |
| timeout_seconds | int | optional default 30, max configured via admin settings |
| background | bool | optional if true, run async and return job_id |
status is one of: pending, running, done, timeout, cancelled.rm -rf /, mkfs, dd if=, :(){ :|:& };, shutdown, reboot, poweroff, halt.
# Create a VPS from a template
curl -X POST /api/vps \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"agent-vm","template":"ubuntu-22-small"}'
# template fields (vcpu, memory_mb, disk_gb, user_data, ttl_minutes) are used
# as defaults; explicit request fields override them.
max_batch_size VMs in parallel. Returns a per-item result array (HTTP 207).curl -X POST /api/vps/batch \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"vms":[{"name":"w1","template":"ubuntu-22-small"},{"name":"w2","template":"ubuntu-22-small"}]}'
# → {"results":[{"index":0,"vps":{...}},{"index":1,"vps":{...}}]}
{"ids":["uuid1","uuid2"]}.background:true for async jobs per VM.curl -X POST /api/vps/batch/exec \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"ids":["uuid1","uuid2"],"command":"uptime","timeout_seconds":10}'
# → {"results":[{"vps_id":"uuid1","stdout":"...","exit_code":0},...]}
{"name":"my-key","public_key":"ssh-ed25519 ..."}.Billing is prepaid. Running VMs are charged per-minute based on their plan's hourly rate. Minimum top-up: $5.00. Maximum top-up: $50.00.
url to complete payment.curl -X POST /api/billing/add-funds \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"amount":10}'
# → {"url":"https://checkout.stripe.com/..."}
limit (default 20), offset (default 0).{"email":"ops@example.com"}.
Access tokens (prefix vtk_) are long-lived alternatives to JWTs. Ideal for CI/CD pipelines and agents. Tokens can optionally have a spend limit.
token field is only present in the creation response.curl -X POST /api/tokens \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"ci-deploy"}'
# → {"id":"...","name":"ci-deploy","token":"vtk_abc123..."}
{"status":"ok"} when the API is up.LiteVPS API · openapi.json