VibeCloud Agent Quickstart
⬇ Download .md Sign in

VibeCloud Automation Guide

English

1. How to use this file

Download vibecloud_guide.md from the VibeCloud UI and place it in the root of your application repository.

Before asking Claude (or any AI agent) to deploy, tell it to read vibecloud_guide.md first. This file explains everything an agent needs: authenticate, list packages, create a VPS or database, poll the provisioning job, use the returned credentials to deploy, manage services, and recover from common gotchas.

Recommended repository layout:

my-application/
  vibecloud_guide.md
  .env_vibecloud
  package.json
  src/

Use .env_vibecloud to store the VibeCloud API URL and API token. Do not commit .env_vibecloud to git.

Hosts (important):

  • UI / web app: https://vibecloud.vn — humans log in, manage services, top up balance, generate tokens.
  • API: https://api.vibecloud.vn — every POST /api/... / GET /api/... call in this guide goes here. The UI host does not serve /api.

2. Get an API token

Open the VibeCloud UI at https://vibecloud.vn, sign in with your email, then go to API Keys and create a key for agent automation. The key has the prefix vc_live_.

You can also use the helper script (point it at the API host):

./scripts/vibecloud-auth.sh https://api.vibecloud.vn

On Windows PowerShell:

.\scripts\vibecloud-auth.ps1 -ApiUrl https://api.vibecloud.vn

The command writes .env_vibecloud in the current directory:

VIBECLOUD_API_URL=https://api.vibecloud.vn
VIBECLOUD_API_TOKEN=vc_live_xxx

Authenticate every request with the standard bearer header:

curl -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" ...

3. What vc_live_* tokens can and can't do

vc_live_* automation tokens are scoped for infrastructure work. Endpoint matrix:

Capability Endpoint vc_live_* works?
List packages GET /api/packages ✅ (no auth even needed)
List public prices GET /api/prices ✅ (no auth needed)
Create LXC / database POST /api/lxc, POST /api/databases
Poll job GET /api/jobs/:id
List / get / stop / start / delete / rebuild / resize a service /api/services/*, /api/lxc/:id/*
Check account balance GET /api/me ❌ HTTP 401 (UI session only)
Top up funds POST /api/payments/vietqr ❌ HTTP 401 (UI session only)
Manage API keys POST /api/api-keys, DELETE /api/api-keys/:id ❌ HTTP 401 (UI session only)

If an agent needs to check the balance, the human should top up via the UI and tell the agent "you have enough budget". The agent will see HTTP 402 Insufficient credit if it tries to provision beyond the available balance — see §11.

4. List available packages (optional but recommended)

curl "$VIBECLOUD_API_URL/api/packages"

Returns the list of preset packages with slug, name, cpu, ram_gb, disk_gb. Pick a slug like standard-2 to use in §5/§6.

5. Create an LXC VPS

VibeCloud accepts two sizing shapes. Pick whichever fits:

Mixing the two (slug + dims at the same time) returns HTTP 422.

Using a package

curl -X POST "$VIBECLOUD_API_URL/api/lxc" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"my-app","package_slug":"standard-2"}'

Using custom sizing

curl -X POST "$VIBECLOUD_API_URL/api/lxc" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"my-app","cpu":2,"ram_gb":2,"disk_gb":30}'

The response is a job, not a finished VPS:

{
  "id": "65f00000000000000000000a",
  "type": "create_lxc",
  "status": "pending",
  "result": null,
  "error": null,
  "attempts": 0,
  "max_attempts": 3,
  "created_at": "...",
  "updated_at": "..."
}

Provisioning takes 60–180 s. Poll the job (see §7).

6. Create a database instance

Same two shapes. engine is required and must be one of mongodb, postgresql, mysql.

Using a package

curl -X POST "$VIBECLOUD_API_URL/api/databases" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"my-app","engine":"mongodb","package_slug":"standard-2"}'

Using custom sizing

curl -X POST "$VIBECLOUD_API_URL/api/databases" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"my-app","engine":"postgresql","cpu":2,"ram_gb":2,"disk_gb":30}'

Returns a job, same shape as the LXC job above.

7. Poll the job until it finishes

curl "$VIBECLOUD_API_URL/api/jobs/<job_id>" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

status transitions through one of these terminal states:

status meaning what to do
pending queued, not started yet wait + poll again in 3–5 s
running actively provisioning wait + poll again in 3–5 s
retrying last attempt failed, will auto-retry wait + poll again in 10–30 s
succeeded done — read result proceed to §8
failed exhausted retries — read error inspect error; you may POST /api/jobs/:id/retry after fixing the issue
cancelled admin cancelled the job stop polling

Recommended polling pattern (bash):

JOB_ID="...id from create call..."
for i in {1..60}; do
  RESP=$(curl -s "$VIBECLOUD_API_URL/api/jobs/$JOB_ID" \
    -H "Authorization: Bearer $VIBECLOUD_API_TOKEN")
  STATUS=$(echo "$RESP" | python3 -c 'import json,sys; print(json.load(sys.stdin)["status"])')
  if [ "$STATUS" = "succeeded" ]; then
    echo "$RESP" | python3 -m json.tool
    break
  fi
  if [ "$STATUS" = "failed" ] || [ "$STATUS" = "cancelled" ]; then
    echo "$RESP" >&2
    exit 1
  fi
  sleep 5
done

When status=succeeded, result is the full service object: id, kind, status, name, ip_address, cpu/ram_gb/disk_gb, power_state, hourly_rate_vnd, credentials (LXC) or databases[] (database service), created_at, etc.

8. Use the credentials

LXC — SSH in and deploy

result.credentials contains root_password, ssh_private_key (PEM), ssh_public_key. result.ip_address is the public IP.

The PEM is returned as a standard JSON string with \n-escaped newlines (use any standard JSON parser — json.loads works fine, no special flags). Save it and chmod 600:

mkdir -p ~/.ssh
python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["result"]["credentials"]["ssh_private_key"])' job.json > ~/.ssh/vibecloud_my_app
chmod 600 ~/.ssh/vibecloud_my_app
ssh -i ~/.ssh/vibecloud_my_app root@<ip_address>

The image is a fresh Ubuntu 24.04 LXC. It ships minimalcurl and ca-certificates are NOT preinstalled. Always run this once before downloading anything:

ssh -i ~/.ssh/vibecloud_my_app root@<ip_address> \
  'DEBIAN_FRONTEND=noninteractive apt-get update -q && apt-get install -yq curl ca-certificates'

Database — connect via the returned connection string

result.databases[0] contains engine, host, port, database, username, password, connection_string. The connection string is ready to drop into your app's env var:

# example for mongodb
export DATABASE_URL=$(jq -r '.result.databases[0].connection_string' job.json)

For multiple logical databases on the same instance, see §10.

9. Manage running services

# List your services
curl "$VIBECLOUD_API_URL/api/services" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

# Get one service (includes credentials)
curl "$VIBECLOUD_API_URL/api/services/<service_id>" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

# Stop / start (you keep paying while stopped — destroy if you don't need it)
curl -X POST "$VIBECLOUD_API_URL/api/services/<service_id>/stop"   -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"
curl -X POST "$VIBECLOUD_API_URL/api/services/<service_id>/start"  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

# Delete permanently (frees the IP after a 3h cooldown for ARP cache safety)
curl -X DELETE "$VIBECLOUD_API_URL/api/services/<service_id>" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

LXC-specific:

# Resize CPU / RAM / disk (disk can only grow). Body matches LxcResizeRequest:
curl -X POST "$VIBECLOUD_API_URL/api/lxc/<service_id>/resize" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cpu":4,"ram_gb":8,"disk_gb":60}'

# Rebuild — destroys and recreates the LXC with the SAME ip + credentials.
# Returns a job, poll it like §7.
curl -X POST "$VIBECLOUD_API_URL/api/services/<service_id>/rebuild" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

Database-specific:

# Add another logical database to an existing instance (same VPS, separate DB):
curl -X POST "$VIBECLOUD_API_URL/api/databases/<service_id>/databases" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"another-app"}'

# Rotate a database's password:
curl -X POST "$VIBECLOUD_API_URL/api/databases/<service_id>/databases/<db_name>/change-password" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

10. Operational gotchas

Reused IP triggers SSH "REMOTE HOST IDENTIFICATION HAS CHANGED" When you delete an LXC and a new one later gets the same IP (after the 3-hour cooldown), the new host has a different SSH host key. Your ~/.ssh/known_hosts still has the old one. Clear it:

ssh-keygen -R <ip_address>
# then ssh normally; accept the new fingerprint

Outbound SMTP (ports 25/465/587) is blocked A firewall security group named block-smtp is attached to every new LXC to prevent abuse. If your app legitimately needs to send mail, use an HTTP-API mail provider (SendGrid, Mailgun, Resend, AWS SES).

Stopped services still bill stop only powers the container off — it still occupies disk and an IP, so you keep paying the hourly rate. To stop paying, DELETE the service.

Provisioning vs power state Service status=active means VibeCloud finished provisioning. power_state=running means the LXC kernel is up. After a stop, status stays active but power_state becomes stopped.

11. Billing

12. Common error responses

HTTP Meaning What to do
401 Missing / invalid / expired token Re-check the Authorization: Bearer ... header, or re-run the auth script. vc_live_* tokens are also rejected by /api/me and the payment endpoints — those need a UI session.
402 Insufficient credit for the requested service Ask the human to top up via https://vibecloud.vn.
404 Service / job / package not found, or package_slug references an inactive/deleted package Double-check the id / slug. Use GET /api/packages to list current valid slugs.
409 Conflicting state (e.g. trying to delete a running LXC, resize while provisioning) Read the detail field — usually you need to wait for the previous job or stop the service first.
422 Schema validation — typo in field, wrong type, both package_slug and explicit dims passed at once Read the detail array; it points at the failing field.

Tiếng Việt

1. Cách dùng file này

Tải file vibecloud_guide.md từ giao diện VibeCloud và đặt file này ở thư mục gốc của repository ứng dụng.

Trước khi yêu cầu Claude (hoặc agent AI bất kỳ) deploy, hãy bảo nó đọc vibecloud_guide.md trước. File này hướng dẫn agent: xác thực, liệt kê package, tạo VPS hoặc database, poll job provisioning, dùng credential trả về để deploy, quản lý service, và xử lý các vấn đề thường gặp.

Cấu trúc repository khuyến nghị:

my-application/
  vibecloud_guide.md
  .env_vibecloud
  package.json
  src/

Dùng .env_vibecloud để lưu VibeCloud API URL và API token. Không commit .env_vibecloud lên git.

Hosts (quan trọng):

  • Web UI: https://vibecloud.vn — người dùng đăng nhập, quản lý service, nạp tiền, tạo token.
  • API: https://api.vibecloud.vn — mọi lệnh POST /api/... / GET /api/... trong tài liệu này đều gọi tới host này. Host UI không phục vụ /api.

2. Lấy API token

Mở https://vibecloud.vn, đăng nhập, vào API Keys và tạo key cho agent automation. Key có prefix vc_live_.

Hoặc dùng helper script (truyền API host):

./scripts/vibecloud-auth.sh https://api.vibecloud.vn

Trên Windows PowerShell:

.\scripts\vibecloud-auth.ps1 -ApiUrl https://api.vibecloud.vn

Lệnh tạo file .env_vibecloud ở thư mục hiện tại:

VIBECLOUD_API_URL=https://api.vibecloud.vn
VIBECLOUD_API_TOKEN=vc_live_xxx

Mọi request gắn header:

curl -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" ...

3. Token vc_live_* làm được gì và không làm được gì

Khả năng Endpoint vc_live_* được?
Liệt kê package GET /api/packages ✅ (không cần auth)
Xem giá public GET /api/prices ✅ (không cần auth)
Tạo LXC / database POST /api/lxc, POST /api/databases
Poll job GET /api/jobs/:id
List / get / stop / start / delete / rebuild / resize service /api/services/*, /api/lxc/:id/*
Xem số dư tài khoản GET /api/me ❌ HTTP 401 (chỉ UI session)
Nạp tiền POST /api/payments/vietqr ❌ HTTP 401 (chỉ UI session)
Quản lý API key POST /api/api-keys, DELETE /api/api-keys/:id ❌ HTTP 401 (chỉ UI session)

Nếu agent cần kiểm tra số dư, người dùng nên nạp tiền qua UI rồi báo "bạn đủ tiền". Agent sẽ thấy HTTP 402 Insufficient credit nếu cố tạo service vượt quá số dư — xem §11.

4. Liệt kê các package có sẵn (khuyến nghị)

curl "$VIBECLOUD_API_URL/api/packages"

Trả về danh sách package preset gồm slug, name, cpu, ram_gb, disk_gb. Chọn slug như standard-2 để dùng ở §5/§6.

5. Tạo LXC VPS

VibeCloud nhận hai dạng sizing. Chọn dạng tiện hơn:

Truyền cả hai cùng lúc sẽ trả HTTP 422.

Theo package

curl -X POST "$VIBECLOUD_API_URL/api/lxc" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"my-app","package_slug":"standard-2"}'

Custom sizing

curl -X POST "$VIBECLOUD_API_URL/api/lxc" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"my-app","cpu":2,"ram_gb":2,"disk_gb":30}'

Response là một job, không phải VPS đã hoàn tất:

{
  "id": "65f00000000000000000000a",
  "type": "create_lxc",
  "status": "pending",
  "result": null,
  "error": null,
  "attempts": 0,
  "max_attempts": 3
}

Provisioning mất 60–180 giây. Poll job (xem §7).

6. Tạo database instance

Hai dạng tương tự. engine bắt buộc, là một trong: mongodb, postgresql, mysql.

Theo package

curl -X POST "$VIBECLOUD_API_URL/api/databases" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"my-app","engine":"mongodb","package_slug":"standard-2"}'

Custom sizing

curl -X POST "$VIBECLOUD_API_URL/api/databases" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"my-app","engine":"postgresql","cpu":2,"ram_gb":2,"disk_gb":30}'

7. Poll job tới khi xong

curl "$VIBECLOUD_API_URL/api/jobs/<job_id>" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

status đi qua một trong các trạng thái:

status nghĩa hành động
pending đang chờ poll lại sau 3–5 giây
running đang chạy poll lại sau 3–5 giây
retrying lần thử trước fail, sẽ auto retry poll lại sau 10–30 giây
succeeded xong — đọc result sang §8
failed hết retry — đọc error xem error; có thể POST /api/jobs/:id/retry sau khi fix
cancelled admin huỷ dừng poll

Pattern poll khuyến nghị (bash):

JOB_ID="...id từ lệnh create..."
for i in {1..60}; do
  RESP=$(curl -s "$VIBECLOUD_API_URL/api/jobs/$JOB_ID" \
    -H "Authorization: Bearer $VIBECLOUD_API_TOKEN")
  STATUS=$(echo "$RESP" | python3 -c 'import json,sys; print(json.load(sys.stdin)["status"])')
  if [ "$STATUS" = "succeeded" ]; then echo "$RESP" | python3 -m json.tool; break; fi
  if [ "$STATUS" = "failed" ] || [ "$STATUS" = "cancelled" ]; then echo "$RESP" >&2; exit 1; fi
  sleep 5
done

Khi status=succeeded, result là service object đầy đủ: id, kind, status, name, ip_address, cpu/ram_gb/disk_gb, power_state, hourly_rate_vnd, credentials (LXC) hoặc databases[] (database), v.v.

8. Dùng credential

LXC — SSH vào để deploy

result.credentialsroot_password, ssh_private_key (PEM), ssh_public_key. result.ip_address là IP public.

PEM trả về là JSON string chuẩn (xuống dòng escape \n — dùng parser JSON nào cũng được). Lưu file và chmod 600:

mkdir -p ~/.ssh
python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["result"]["credentials"]["ssh_private_key"])' job.json > ~/.ssh/vibecloud_my_app
chmod 600 ~/.ssh/vibecloud_my_app
ssh -i ~/.ssh/vibecloud_my_app root@<ip_address>

Image là Ubuntu 24.04 LXC fresh, không có sẵn curlca-certificates. Luôn chạy trước khi tải gì:

ssh -i ~/.ssh/vibecloud_my_app root@<ip_address> \
  'DEBIAN_FRONTEND=noninteractive apt-get update -q && apt-get install -yq curl ca-certificates'

Database — connect bằng connection string

result.databases[0]engine, host, port, database, username, password, connection_string. Connection string sẵn để dùng:

export DATABASE_URL=$(jq -r '.result.databases[0].connection_string' job.json)

Tạo nhiều DB logic trên cùng instance, xem §9.

9. Quản lý service

# List service của bạn
curl "$VIBECLOUD_API_URL/api/services" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

# Get một service (kèm credentials)
curl "$VIBECLOUD_API_URL/api/services/<service_id>" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

# Stop / start (stop vẫn tính tiền — destroy nếu không dùng nữa)
curl -X POST "$VIBECLOUD_API_URL/api/services/<service_id>/stop"  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"
curl -X POST "$VIBECLOUD_API_URL/api/services/<service_id>/start" -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

# Xoá vĩnh viễn (IP được trả về pool sau 3 giờ cooldown để tránh stale ARP)
curl -X DELETE "$VIBECLOUD_API_URL/api/services/<service_id>" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

LXC riêng:

# Resize CPU / RAM / disk (disk chỉ tăng được). Body theo LxcResizeRequest:
curl -X POST "$VIBECLOUD_API_URL/api/lxc/<service_id>/resize" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cpu":4,"ram_gb":8,"disk_gb":60}'

# Rebuild — xoá rồi tạo lại LXC, GIỮ NGUYÊN ip và credentials. Trả về job.
curl -X POST "$VIBECLOUD_API_URL/api/services/<service_id>/rebuild" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

Database riêng:

# Thêm DB logic mới trên cùng instance (cùng VPS, DB tách):
curl -X POST "$VIBECLOUD_API_URL/api/databases/<service_id>/databases" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app_name":"another-app"}'

# Đổi password của một DB:
curl -X POST "$VIBECLOUD_API_URL/api/databases/<service_id>/databases/<db_name>/change-password" \
  -H "Authorization: Bearer $VIBECLOUD_API_TOKEN"

10. Các vấn đề thường gặp

IP tái sử dụng → SSH báo "REMOTE HOST IDENTIFICATION HAS CHANGED" Khi delete một LXC và sau đó (sau cooldown 3 giờ) có LXC mới nhận lại IP đó, host key SSH đã đổi. known_hosts cũ vẫn còn. Clear:

ssh-keygen -R <ip_address>
# rồi ssh lại như thường, accept fingerprint mới

SMTP outbound (cổng 25/465/587) bị chặn Security group block-smtp được attach vào mọi LXC mới để chống abuse. Nếu app cần gửi mail thật, dùng nhà cung cấp HTTP API (SendGrid, Mailgun, Resend, AWS SES).

Stop vẫn bị tính tiền stop chỉ tắt container — vẫn giữ disk và IP, nên vẫn bị tính phí giờ. Muốn ngưng tính phí, DELETE service.

Provisioning vs power state Service status=active nghĩa là VibeCloud đã provision xong. power_state=running nghĩa là kernel LXC đang chạy. Sau stop, status vẫn là active nhưng power_state thành stopped.

11. Cách tính phí

12. Các lỗi thường gặp

HTTP Nghĩa Cách xử lý
401 Thiếu / sai / hết hạn token Check Authorization: Bearer ..., hoặc chạy lại auth script. Token vc_live_* bị từ chối ở /api/me và payments — cần UI session.
402 Không đủ tiền cho service yêu cầu Nhờ người dùng nạp qua https://vibecloud.vn.
404 Không thấy service / job / package, hoặc package_slug trỏ tới package inactive/đã xoá Check lại id / slug. Dùng GET /api/packages xem slug còn hiệu lực.
409 Conflict state (ví dụ xoá LXC đang chạy, resize khi đang provisioning) Đọc detail — thường phải chờ job trước xong hoặc stop service.
422 Validation schema — sai field, sai type, truyền cả package_slug lẫn dims cùng lúc Đọc detail, nó trỏ tới field bị lỗi.