Tham chiếu API

API Hosting

Hosting web dùng panel CyberPanel. Mua là ĐỒNG BỘ và có NGAY: lệnh mua tạo tài khoản panel + website ngay trong lượt gọi (thường 10–20 giây) và trả HTTP 200 provision_status = ready kèm thông tin đăng nhập (về sau đọc lại ở /hosting/info hoặc /hosting/credentials với khoá toàn quyền). Hiếm khi máy chủ hỏng sau lúc đã trừ tiền ⇒ HTTP 202 provisioning + charged: true — bộ phận kỹ thuật hoàn tất (ready), không được thì huỷ + hoàn tiền (failed + refunded_amount). Gia hạn theo giá ghi trên đơn. Nâng gói chỉ trong cùng nhóm; máy chủ hiện tại hết chỗ ⇒ 409 CAPACITY_UNAVAILABLE (chuyển máy chủ chỉ làm trên web). Số liệu dung lượng / băng thông do máy chủ đẩy về mỗi giờ. Không có chuyển quyền / rao chợ / đăng nhập một chạm qua API. Khách tự trỏ bản ghi A của tên miền về panel.server_ip.

Trên trang này
  1. Tổng quan
  2. Mua & đăng nhập panel
  3. Trạng thái đơn
  4. Tên miền & danh mục
  5. Thời hạn & gia hạn
  6. Nâng gói & đổi chu kỳ
  7. Dung lượng & băng thông
  8. Luật riêng
  9. Nhịp thao tác
  10. Mã lỗi riêng
  11. GET /hosting/products
  12. POST /hosting/quote
  13. POST /hosting/buy
  14. GET /hosting/list
  15. GET /hosting/info
  16. POST /hosting/renew
  17. POST /hosting/auto-renew
  18. POST /hosting/change-password
  19. POST /hosting/upgrade
  20. POST /hosting/change-cycle
  21. POST /hosting/delete
  22. GET /hosting/usage
  23. GET /hosting/credentials

Tổng quan

Địa chỉ gốc của các endpoint trên trang này:

Base URL
https://cloudmoon.net/api/v1
EndpointViệcQuyền khoá
GET /hosting/products Danh mục gói hosting: cycles = chu kỳ mua được (ngắn → dài), pricing = giá từng chu kỳ (amount đã trừ chiết khấu đại lý… Chỉ đọc
POST /hosting/quote BÁO GIÁ — không trừ tiền, không ghi gì, khoá chỉ đọc gọi được. Mua mới: {product_id, billing_cycle, domain} — CÙNG bộ k… Chỉ đọc
POST /hosting/buy Mua hosting — trừ tiền và tạo tài khoản panel NGAY trong lượt gọi (thường 10–20 giây — đặt thời gian chờ HTTP từ 90 giâ… Toàn quyền
GET /hosting/list Mọi hosting của tài khoản (không kèm mật khẩu), mỗi đơn kèm provision_status, gói, hạn mức, số liệu sử dụng, billing, a… Chỉ đọc
GET /hosting/info Chi tiết một hosting: provision_status (ready · provisioning · failed · expired · deleted), order_status / account_stat… Chỉ đọc
POST /hosting/renew Gia hạn một chu kỳ, trừ ví ngay. Giá = GIÁ GHI TRÊN ĐƠN (billing.price_renew) — báo giá trước bằng /hosting/quote {orde… Toàn quyền
POST /hosting/auto-renew Bật/tắt tự gia hạn (tới hạn hệ thống tự trừ ví theo giá ghi trên đơn). ĐẶT giá trị — gửi lại cùng lệnh không lật ngược;… Toàn quyền
POST /hosting/change-password Đổi mật khẩu panel; bỏ trống new_password ⇒ hệ thống sinh 16 ký tự. Luật: 8–64 ký tự, chỉ chữ · số · !@#$%^&*._- . Mật … Toàn quyền
POST /hosting/upgrade Nâng gói (giữ chu kỳ), trừ ví ngay. Chỉ lên gói CÙNG NHÓM, dung lượng không nhỏ hơn, còn hàng. Phí = max(0, giá kỳ gói … Toàn quyền
POST /hosting/change-cycle Đổi chu kỳ thanh toán (giữ gói) — KHÔNG thu tiền ngay, giá kỳ mới áp từ lần gia hạn kế tiếp. Chỉ sang chu kỳ ĐANG BÁN v… Toàn quyền
POST /hosting/delete Xoá hosting (website + tài khoản panel) — KHÔNG hoàn tiền, không khôi phục. Bắt buộc confirm = đúng order_code. Đơn đan… Toàn quyền
GET /hosting/usage Dung lượng + băng thông đang dùng và hạn mức của gói (0 = không giới hạn). Số do máy chủ đẩy về mỗi giờ (synced_at); st… Chỉ đọc
GET /hosting/credentials Thông tin đăng nhập panel (url · server_ip · username · password) — khoá TOÀN QUYỀN, chỉ hosting ready và đang hoạt độn… Toàn quyền

Giá đại lý: Danh mục, báo giá và lệnh mua trả về (và trừ ví) giá đã trừ chiết khấu theo cấp đại lý; gia hạn theo GIÁ GHI TRÊN ĐƠN (giá lúc mua — đã trừ chiết khấu khi ấy — cập nhật khi nâng gói hoặc đổi chu kỳ) — không theo giá niêm yết hiện hành. — xem mục Tài khoản đại lý.

Mua & đăng nhập panel

Hosting được tạo ngay trong lệnh mua — không xếp hàng như Cloud VPS, không chờ bàn giao như Dedicated Server. Lệnh mua thường mất 10–20 giây; hãy đặt thời gian chờ HTTP của bạn từ 90 giây trở lên.

  1. POST /hosting/buy với {product_id, billing_cycle, domain} kiểm hết (gói còn hàng, chu kỳ, tên miền, số dư khả dụng, giới hạn lượt mua) rồi trừ ví và tạo tài khoản panel CyberPanel kèm website. Thành công ⇒ HTTP 200, provision_status: "ready", charged: true, price_buy (số đã trừ) và panel: url · server_ip · username · password.
  2. Trỏ bản ghi A của tên miền về panel.server_ip.
  3. Đăng nhập panel ở panel.url từ mốc panel.ready_at (khoảng 90 giây sau khi tạo).
  • Mật khẩu panel có ngay trong câu trả lời của lệnh mua; về sau đọc lại bằng GET /hosting/info (trường panel.password) hoặc GET /hosting/credentials — cả hai cần khoá Toàn quyền và hosting đang hoạt động (tạm ngưng, bị khoá hay đang chuyển máy chủ thì ẩn). Muốn đổi ⇒ POST /hosting/change-password.
  • website_verified: true = website đã có trên máy chủ lúc trả lời; false / null = chưa xác nhận kịp (website đôi khi hiện muộn vài phút, bộ phận kỹ thuật đã được báo để kiểm) — hosting vẫn ready, tài khoản panel dùng được.
  • Sự cố sau khi đã trừ tiền (hiếm): HTTP 202, provision_status: "provisioning", charged: true, có order_code, panel: null. Đơn đã tồn tại và đã trả tiền — đừng mua lại. Bộ phận kỹ thuật hoàn tất ⇒ info chuyển ready; không hoàn tất được ⇒ đơn bị huỷ và hoàn đủ số đã trừ: provision_status: "failed" + refunded_amount. Hỏi info thưa thôi — mỗi 5–10 phút là đủ.
  • Lệnh mua bị chối (thiếu tiền, hết hàng, tên miền đã có hosting khác dùng, giá vừa tăng…) thì chưa trừ đồng nào. Riêng 409 PRICE_CHANGED: báo giá lại rồi gửi lệnh mới với Idempotency-Key mới.
  • Mạng đứt khi đang chờ câu trả lời ⇒ gửi lại với đúng Idempotency-Key cũ: nhận lại kết quả lần đầu (hoặc 409 IDEMPOTENCY_PENDING nếu lượt đầu chưa xong) — không mua hai lần. Không kèm khoá thì lượt gửi lại bị một bước kiểm chối — thường 409 DOMAIN_IN_USE (tên miền đã thuộc hosting vừa tạo), cũng có thể mã khác như 409 OUT_OF_STOCK (lượt đầu vừa lấy chỗ cuối) — nên mất câu trả lời mà không có khoá thì đối chiếu /hosting/list trước khi mua lại. Luôn gửi Idempotency-Key.
Ví dụ — HTTP 202 (sự cố sau khi trừ tiền)
{
    "status": "success",
    "msg": "Đã trừ tiền — hosting đang được hoàn tất khởi tạo",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "domain": "khachhang.com",
        "provision_status": "provisioning",
        "charged": true,
        "product_id": 1,
        "billing_cycle": "onemonth",
        "price_buy": 50000,
        "time_expire": "2026-11-12",
        "panel": null,
        "website_verified": null,
        "note": "Đơn đã trừ tiền, bộ phận kỹ thuật đang hoàn tất khởi tạo — hỏi GET /hosting/info?order_code= tới khi provision_status = ready"
    }
}

Trạng thái đơn

Hosting có hai lớp trạng thái: order_status (thời hạn) và account_status (tài khoản trên máy chủ). provision_status gộp hai lớp thành một chữ cho bộ tích hợp — cùng tên với các sản phẩm khác. Mỗi ô bên trái ghi provision_status ở trên cùng, rồi tới order_status và account_status:

provision_status
order_status
account_status
Nghĩa
ready
active
active
Đang hoạt động.
ready
pending_expired
suspended
Tạm ngưng vì quá hạn — chỉ còn gia hạn, bật/tắt tự gia hạn và xoá (việc khác 409 RENEW_REQUIRED); thông tin đăng nhập bị ẩn.
ready
active
suspended
Bộ phận hỗ trợ tạm khoá — gia hạn và tự gia hạn được nhưng không mở khoá; việc khác 409 SUSPENDED. Liên hệ hỗ trợ.
provisioning
active
failed
Lệnh mua gặp sự cố sau khi đã trừ tiền — bộ phận kỹ thuật đang hoàn tất. Chỉ còn bật/tắt tự gia hạn; việc khác 409 REBUILDING.
provisioning
còn hạn / tạm ngưng
migrating
Đang chuyển sang máy chủ khác — gia hạn và tự gia hạn được; việc khác 409 MIGRATING.
failed
expired
failed
Không hoàn tất được — đơn đã huỷ và hoàn đủ (refunded_amount); lệnh thao tác nhận 409 ORDER_CANCELLED. Về sau, khi đơn được dọn, chuyển deleted.
deleted
expired
deleted · archived
Đã xoá — bạn xoá (deleted), hoặc tài khoản bị dọn sau thời gian tạm ngưng (archived). Không gia hạn, không khôi phục qua API; lệnh thao tác nhận 409 ORDER_DELETED.
expired
expired
còn lại
Hết hạn hẳn (409 ORDER_EXPIRED) — hiếm gặp: đơn quá hạn thường đi thẳng sang deleted khi tài khoản bị dọn.
  • Chốt trạng thái ở bảng trên chỉ áp cho lệnh thao tác (gia hạn, nâng gói, đổi chu kỳ, đổi mật khẩu, xoá…), báo giá trên đơn và credentials; info · list · usage đọc được đơn ở mọi trạng thái — kể cả đơn đã huỷ (để đối soát refunded_amount) hay đã xoá.
  • features — khả năng của API với hosting: renew · auto_renew · change_password · upgrade · change_cycle · delete là true; migrate (chuyển máy chủ) · transfer (chuyển quyền) là false — hai việc này chỉ làm trên trang quản lý hosting.
  • allowed_actions (có ở cả list lẫn info) — việc làm được ngay lúc này, theo cùng luật với các nút trên web: tên nào vắng mặt thì lệnh ấy đang bị chối (tạm ngưng, đang hoàn tất khởi tạo, máy chủ bảo trì, đang rao bán trên chợ…). Không tính nhịp thao tác — xem mục Nhịp thao tác.
  • marketplace: true — hosting đang được rao bán trên Chợ: xoá, nâng gói, đổi chu kỳ nhận 409 LISTED_ON_MARKETPLACE tới khi huỷ tin rao trên web.

Tên miền & danh mục

  • Mỗi hosting gắn một tên miền (domain) — website chính của tài khoản panel. Gửi dạng ten.com hoặc sub.ten.vn: hệ thống bỏ khoảng trắng hai đầu và đổi sang chữ thường; không kèm http://, đường dẫn hay cổng; tối đa 253 ký tự, mỗi nhãn 1–63 ký tự gồm chữ, số, gạch nối (không mở đầu hay kết thúc bằng gạch nối), đuôi 2–63 chữ cái. Sai ⇒ 400 BAD_REQUEST.
  • Một tên miền chỉ thuộc một hosting còn hiệu lực (đang hoạt động hoặc đang tạm ngưng) trên toàn hệ thống, kể cả hosting khác của chính bạn ⇒ 409 DOMAIN_IN_USE. Hosting đã xoá hoặc đã dọn thì tên miền dùng lại được. Báo giá mua (/hosting/quote) kiểm tên miền y như lệnh mua.
  • Mua hosting không kèm tên miền: tên miền là của bạn, mua ở đâu cũng được — sau khi mua hosting, tự trỏ bản ghi A về panel.server_ip.
  • name — tên gợi nhớ, tối đa 150 ký tự; bỏ trống thì lấy tên miền (cắt còn 150 ký tự).
  • GET /hosting/products bày các gói đang bán; gói tạm hết hàng vẫn có mặt với in_stock: false (lệnh mua nhận 409 OUT_OF_STOCK) — thêm ?in_stock=1 để chỉ lấy gói còn hàng, lọc thêm ?region= · ?group_code=. cycles là mã các chu kỳ mua được (ngắn → dài); pricing là giá từng chu kỳ: amount (giá bạn trả — đã trừ chiết khấu đại lý) · amount_original (giá niêm yết) · months.
  • quota: disk_mb · bandwidth_mb · email · database · websites — 0 là không giới hạn. Mỗi gói thuộc một nhóm (group_code) gắn với một khu vực (region_code · city); nâng gói chỉ trong cùng nhóm.

Thời hạn & gia hạn

  • Thời hạn tính từ lúc mua — time_expire (ngày) có ngay trong câu trả lời của lệnh mua, về sau ở billing.time_expire.
  • POST /hosting/renew cộng một chu kỳ vào hạn hiện tại (không tính lại từ ngày gửi lệnh) và trừ ví ngay. Giá = giá ghi trên đơn (billing.price_renew, bằng billing.price_buy): giá lúc mua — đã gồm chiết khấu đại lý lúc ấy — và được cập nhật khi nâng gói hoặc đổi chu kỳ; không theo giá niêm yết hiện hành, không áp chiết khấu thêm lần nữa. Báo giá trước: POST /hosting/quote với {"order_code": "…", "type": "renew"}; info.renew_until là hạn mới nếu gia hạn một kỳ.
  • Đơn gia hạn theo chu kỳ hiện tại của đơn (billing.billing_cycle), kể cả khi chu kỳ ấy không còn bán cho đơn mới. Muốn kỳ dài hơn ⇒ POST /hosting/change-cycle (mục dưới).
  • Tự gia hạn (billing.renew_auto: "on", đổi bằng POST /hosting/auto-renew với enabled là boolean — lệnh ĐẶT giá trị, gửi lại không lật ngược): trong 7 ngày trước hạn, hệ thống tự gia hạn một chu kỳ khi ví đủ tiền — cùng giá với gia hạn tay. Vẫn chạy trong thời gian tạm ngưng: nạp đủ tiền là hosting tự được gia hạn, rồi được mở lại như gia hạn tay.
  • Qua ngày hết hạn mà chưa gia hạn, đơn chuyển pending_expired (account_status: suspended). Gói hosting đã bị tạm ngưng — website và email trên gói này ngừng hoạt động. Dữ liệu vẫn còn nguyên. Gia hạn trong 10 ngày kể từ ngày hết hạn ⇒ hạn được cộng và hệ thống mở lại hosting; nếu việc mở lại trên máy chủ chưa xong (máy chủ bảo trì hay trục trặc), tiền và hạn vẫn đã ghi nhận và bộ phận kỹ thuật xử lý tiếp — gia hạn thành công không có nghĩa website chắc chắn chạy lại ngay.
  • Sau 10 ngày, tài khoản hosting bị xoá cùng toàn bộ mã nguồn và cơ sở dữ liệu. Đơn chuyển provision_status: "deleted" (account_status: archived) — không gia hạn hay thao tác được nữa (409 ORDER_DELETED). Gia hạn trước hạn, hoặc bật tự gia hạn, là chắc nhất.

Nâng gói & đổi chu kỳ

  • POST /hosting/upgrade với {order_code, product_id} — lên gói lớn hơn, giữ chu kỳ. Gói mới phải cùng nhóm (group_code), dung lượng không nhỏ hơn và còn hàng; khác nhóm hay nhỏ hơn ⇒ 400 NOT_SUPPORTED. Máy chủ hiện tại không đủ chỗ cho gói mới ⇒ 409 CAPACITY_UNAVAILABLE — chuyển máy chủ chỉ làm được trên trang quản lý hosting.
  • Phí nâng gói = max(0, giá kỳ của gói mới − giá đơn đang trả) × số kỳ còn lại (số kỳ tính từ hôm nay tới hạn, tối thiểu 1). Trừ ví ngay; hạn giữ nguyên; giá kỳ của gói mới (đã trừ chiết khấu đại lý lúc nâng) thành giá gia hạn của đơn.
  • applied_on_server: false — đã thu tiền và đơn đã ở gói mới, nhưng máy chủ chưa áp xong hạn mức mới (bộ phận kỹ thuật đã được báo). Đừng gửi lại lệnh nâng gói.
  • POST /hosting/change-cycle với {order_code, billing_cycle} — sang chu kỳ dài hơn đang bán, giữ gói: không thu tiền, hạn giữ nguyên; giá kỳ mới (đã trừ chiết khấu lúc đổi) thành giá gia hạn ngay — lần gia hạn kế, tay hay tự động, thu giá ấy và cộng trọn chu kỳ mới. Chu kỳ ngắn hơn, trùng hoặc không còn bán ⇒ 400 BAD_REQUEST. Lệnh này không nhận Idempotency-Key (không thu tiền).
  • Mỗi lệnh chỉ đổi một thứ — gói hoặc chu kỳ. Báo giá trước: quote với {order_code, type: "upgrade", product_id} hoặc {order_code, type: "change_cycle", billing_cycle} ⇒ amount (số trừ ngay) · cycles_needed · days_left · price_renew (giá gia hạn sau khi đổi) · enough.

Dung lượng & băng thông

  • Số đang dùng là số máy chủ gửi về mỗi giờ: usage.disk_mb · usage.bandwidth_mb và lúc nhận số usage.synced_at có ở list / info.
  • GET /hosting/usage trả thêm hạn mức của gói (quota_disk_mb · quota_bandwidth_mb, 0 là không giới hạn) và stale: true khi đã quá 2 giờ chưa có số mới (hoặc chưa có số nào).
  • Không có lệnh làm mới tức thì — hỏi thưa thôi, mỗi giờ một lần là đủ.

Luật riêng

  • Đổi mật khẩu panel (POST /hosting/change-password): new_password 8–64 ký tự, chỉ gồm chữ, số và !@#$%^&*._-; bỏ trống ⇒ hệ thống sinh 16 ký tự. Mật khẩu mới có trong câu trả lời. Chỉ hosting đang hoạt động.
  • Xoá (POST /hosting/delete, confirm = đúng order_code): xoá website và tài khoản panel — không hoàn tiền, không khôi phục. Hosting tạm ngưng vì quá hạn vẫn xoá được; đang hoàn tất khởi tạo, đang chuyển máy chủ, bị khoá hay đang rao bán trên chợ thì bị chối.
  • Máy chủ của hosting đang bảo trì: đổi mật khẩu, nâng gói, xoá ⇒ 503 MAINTENANCE (thử lại sau); gia hạn, tự gia hạn, đổi chu kỳ vẫn chạy. Khác với dịch vụ hosting tạm dừng bán: danh mục, báo giá mua và lệnh mua nhận 503 SERVICE_DISABLED, hosting đang có vẫn thao tác bình thường (GET /services/status báo hosting: false).
  • Không làm qua API: chuyển máy chủ · chuyển quyền · rao bán trên chợ · đăng nhập panel một chạm · đổi tên gợi nhớ / ghi chú — dùng trang quản lý hosting trên web.
  • Giới hạn lệnh mua qua API: tối đa 10 lượt mua hosting mỗi giờ (429 RATE_LIMITED) — đếm cả hosting mua trên web, tính riêng với các sản phẩm khác. Không có giới hạn số đơn chờ (lệnh mua xong ngay). Số dư xét lệnh mua là số dư khả dụng — đã trừ tiền các lệnh mua Cloud VPS còn chờ tạo máy.
  • Chạy thử (X-Sandbox: 1): lệnh mua trả ready ngay (HTTP 200) kèm panel mẫu (máy chủ panel.sandbox.example, IP thuộc dải dành cho tài liệu 203.0.113.x); mã SANDBOX… dùng được ở mọi lệnh hosting khi vẫn kèm X-Sandbox: 1. Lệnh mua chạy thử trả lại đúng tên miền bạn gửi, nhưng hỏi info bằng mã ấy thì hosting mẫu mang tên miền sandbox-….example (mã chỉ chở gói, chu kỳ và cờ — tên miền không, còn giá và hạn mức dựng lại từ gói hiện hành mỗi lần hỏi) — và nó không lưu gì: đổi mật khẩu, đổi chu kỳ hay xoá mô phỏng không làm info về sau đổi theo, mã không có trong list. Kịch bản PROVISION_FAILED ⇒ HTTP 202 provisioning + charged: true, và hosting mẫu đứng yên ở provisioning (chỉ còn bật/tắt tự gia hạn) — để thử nhánh chờ kỹ thuật; nhánh huỷ + hoàn không mô phỏng được.

Nhịp thao tác trên cùng một hosting

Các lệnh trên cùng một hosting phải cách lệnh trước một khoảng tối thiểu — nhịp này chỉ áp cho lệnh gửi qua API, để chặn lệnh gửi lặp. Các việc trong cùng một dòng dùng chung một đồng hồ. Gửi sớm hơn ⇒ 429 COOLDOWN (header Retry-After cho biết còn bao nhiêu giây); gửi trong lúc máy đang xử lý lệnh khác ⇒ 429 IN_PROGRESS.

LệnhCách lệnh trước trên cùng hosting
Gia hạn · Nâng gói · Đổi chu kỳ1 phút (chung một nhịp)
Đổi mật khẩu1 phút (tính riêng)
Bật/tắt tự gia hạn5 giây (tính riêng)
Xoákhông phải chờ (chỉ một lệnh mỗi lúc trên cùng đơn (429 IN_PROGRESS))

Mã lỗi riêng

Ngoài các mã lỗi chung của mọi endpoint, trang này còn có các mã dưới đây. Hãy rẽ nhánh theo code.

HTTPcodeÝ nghĩaNên làm gì
400 NOT_SUPPORTED Đơn / gói không hỗ trợ thao tác được yêu cầu (vd hạ gói, nâng sang gói khác nhóm, chu kỳ của đơn không còn hợp lệ). Đọc features và allowed_actions trước khi gọi.
400 CONFIRM_REQUIRED Lệnh xoá thiếu trường xác nhận. Gửi confirm bằng đúng order_code.
409 OUT_OF_STOCK Gói tạm hết hàng (trong danh mục gói mang in_stock: false). Chọn gói khác — thêm ?in_stock=1 vào danh mục để chỉ thấy gói còn hàng.
409 REBUILDING Hosting đang được hoàn tất khởi tạo (máy chủ trục trặc lúc mua, đã trừ tiền — bộ phận kỹ thuật đang xử lý). Hỏi /hosting/info tới khi provision_status = ready (hoặc failed + refunded_amount nếu phải huỷ).
409 MIGRATING Hosting đang được chuyển sang máy chủ khác — chỉ gia hạn và bật/tắt tự gia hạn được. Chờ chuyển xong (provision_status = ready) rồi gửi lại.
409 SUSPENDED Hosting đang bị khoá bởi bộ phận hỗ trợ — chỉ gia hạn và bật/tắt tự gia hạn được. Liên hệ hỗ trợ.
409 DOMAIN_IN_USE Tên miền đã có một hosting khác đang dùng. Chọn tên miền khác (hoặc xoá hosting cũ của tên miền ấy trước).
409 CAPACITY_UNAVAILABLE Máy chủ hiện tại của hosting không đủ chỗ cho gói mới. Chuyển máy chủ trên trang quản lý hosting (web), hoặc chọn gói nhỏ hơn.
409 PRICE_CHANGED Giá gói vừa tăng giữa lúc kiểm và lúc trừ tiền — lệnh mua CHƯA trừ đồng nào. Báo giá lại (/hosting/quote) rồi gửi lệnh mua mới (Idempotency-Key mới).
409 ORDER_EXPIRED Đơn đã hết hạn hẳn — tài nguyên đã giải phóng. Không thao tác được nữa; mua máy mới.
409 ORDER_DELETED Đơn đã bị xoá. Không thao tác được nữa.
409 ORDER_CANCELLED Đơn đã bị huỷ vì không khởi tạo được — tiền đã hoàn vào số dư (refunded_amount ở /hosting/info). Đặt mua lại.
409 RENEW_REQUIRED Dịch vụ đang tạm ngưng vì quá hạn. Gia hạn (/hosting/renew) rồi thao tác lại.
409 LISTED_ON_MARKETPLACE Hosting đang được rao bán trên chợ — xoá, nâng gói, đổi chu kỳ bị chặn. Huỷ tin rao trên web rồi gửi lại.
429 COOLDOWN Đơn vừa nhận lệnh cùng nhóm — cần nghỉ giữa hai lệnh (xem bảng Nhịp thao tác). Chờ Retry-After giây.
429 IN_PROGRESS Đơn đang xử lý một lệnh khác (hai lệnh cùng lúc trên một hosting), hoặc đơn vừa thay đổi giữa lúc kiểm và lúc ghi. Chờ Retry-After giây rồi gửi lại.
503 MAINTENANCE Máy chủ của hosting này đang bảo trì — đổi mật khẩu, nâng gói, xoá tạm dừng; gia hạn vẫn được. Thử lại sau.
GET

/hosting/products

Chỉ đọc

Danh mục gói hosting: cycles = chu kỳ mua được (ngắn → dài), pricing = giá từng chu kỳ (amount đã trừ chiết khấu đại lý, amount_original = giá niêm yết, months = số tháng), quota (0 = không giới hạn). Gói tạm hết hàng VẪN có trong danh sách với in_stock: false (đặt mua nhận 409 OUT_OF_STOCK) — thêm ?in_stock=1 để chỉ lấy gói còn hàng. Lọc ?region= · ?group_code=.

GET https://cloudmoon.net/api/v1/hosting/products
Tham sốVị tríBắt buộcMô tả
region query không VN / US / UK …
group_code query không lọc theo nhóm
in_stock query không 1 = chỉ gói còn hàng
Yêu cầu
curl 'https://cloudmoon.net/api/v1/hosting/products' \
  -H 'X-API-Key: ak_...'
Yêu cầu
import requests

r = requests.get(
    "https://cloudmoon.net/api/v1/hosting/products",
    headers={"X-API-Key": "ak_..."},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/products", {
  headers: { "X-API-Key": "ak_..." },
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('GET', '/v1/hosting/products');
print_r($kq);
Phản hồi
{
    "status": "success",
    "msg": "OK",
    "data": {
        "items": [
            {
                "product_id": 1,
                "product_code": "starter",
                "name": "Hosting Starter",
                "description": "",
                "group_code": "vn50",
                "group_label": "Hosting VN — Cụm 1",
                "region_code": "VN",
                "city": "Hà Nội",
                "tier": "standard",
                "in_stock": true,
                "quota": {
                    "disk_mb": 5120,
                    "bandwidth_mb": 0,
                    "email": 5,
                    "database": 0,
                    "websites": 1
                },
                "cycles": [
                    "onemonth",
                    "oneyear"
                ],
                "pricing": {
                    "onemonth": {
                        "amount": 50000,
                        "amount_original": 50000,
                        "billing_cycle": "1 Tháng",
                        "months": 1
                    },
                    "oneyear": {
                        "amount": 500000,
                        "amount_original": 500000,
                        "billing_cycle": "1 Năm",
                        "months": 12
                    }
                }
            }
        ],
        "total": 1,
        "discount_percent": 0,
        "currency": "VND"
    }
}
POST

/hosting/quote

Chỉ đọc

BÁO GIÁ — không trừ tiền, không ghi gì, khoá chỉ đọc gọi được. Mua mới: {product_id, billing_cycle, domain} — CÙNG bộ kiểm với lệnh mua (gói mua được, chu kỳ, tên miền hợp lệ và chưa có hosting khác dùng); enough so với balance_available (= số dư − tiền các lệnh mua VPS còn chờ tạo máy). Đơn có sẵn: {order_code, type: renew} ⇒ giá gia hạn + hạn mới · {order_code, type: upgrade, product_id} ⇒ phí nâng gói + giá kỳ sau · {order_code, type: change_cycle, billing_cycle} ⇒ phí 0 + giá kỳ mới.

POST https://cloudmoon.net/api/v1/hosting/quote
Tham sốVị tríBắt buộcMô tả
product_id body không mua mới / nâng gói
billing_cycle body không mua mới / đổi chu kỳ
domain body không mua mới
order_code body không đơn có sẵn
type body không renew | upgrade | change_cycle (đơn có sẵn)

Chạy thử Lệnh đọc — gửi kèm X-Sandbox: 1 vẫn chạy như thường (không đổi gì). Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu.

Yêu cầu
curl -X POST 'https://cloudmoon.net/api/v1/hosting/quote' \
  -H 'X-API-Key: ak_...' \
  -H 'Content-Type: application/json' \
  -d '{"product_id":1,"billing_cycle":"onemonth","domain":"khachhang.com"}'
Yêu cầu
import requests

r = requests.post(
    "https://cloudmoon.net/api/v1/hosting/quote",
    headers={"X-API-Key": "ak_..."},
    json={"product_id": 1, "billing_cycle": "onemonth", "domain": "khachhang.com"},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/quote", {
  method: "POST",
  headers: {
    "X-API-Key": "ak_...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ product_id: 1, billing_cycle: "onemonth", domain: "khachhang.com" }),
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('POST', '/v1/hosting/quote', ['product_id' => 1, 'billing_cycle' => 'onemonth', 'domain' => 'khachhang.com']);
print_r($kq);
Thân yêu cầu
{
    "product_id": 1,
    "billing_cycle": "onemonth",
    "domain": "khachhang.com"
}
Phản hồi
{
    "status": "success",
    "msg": "OK",
    "data": {
        "type": "buy",
        "product_id": 1,
        "billing_cycle": "onemonth",
        "domain": "khachhang.com",
        "amount": 50000,
        "amount_original": 50000,
        "discount_percent": 0,
        "time_expire": "2026-11-12",
        "balance": 500000,
        "balance_available": 500000,
        "enough": true
    }
}
POST

/hosting/buy

Toàn quyền

Mua hosting — trừ tiền và tạo tài khoản panel NGAY trong lượt gọi (thường 10–20 giây — đặt thời gian chờ HTTP từ 90 giây): HTTP 200 provision_status = ready kèm panel (url · server_ip · username · password — về sau đọc lại mật khẩu ở /hosting/info hoặc /hosting/credentials, khoá toàn quyền). Máy chủ hỏng sau lúc đã trừ tiền ⇒ HTTP 202 provisioning + charged: true + order_code — hỏi /hosting/info tới khi ready (hoặc failed + refunded_amount nếu phải huỷ). Tên miền: viết thường, chưa có hosting khác dùng (409 DOMAIN_IN_USE). Panel đăng nhập được sau panel.ready_at (~90 giây sau khi tạo). Lượt mua mỗi giờ: xem mục Giới hạn.

POST https://cloudmoon.net/api/v1/hosting/buy
Tham sốVị tríBắt buộcMô tả
Idempotency-Key header không chống trừ tiền hai lần khi gửi lại
product_id body có id số trong /hosting/products
billing_cycle body có một khoá trong cycles của gói
domain body có tên miền của website
name body không tên gợi nhớ (≤ 150 ký tự; bỏ trống = tên miền, cắt còn 150 ký tự)

Chạy thử Gửi kèm X-Sandbox: 1: máy chủ kiểm như lượt thật rồi trả kết quả mô phỏng cùng khuôn — không trừ tiền, không đổi gì. Kịch bản lỗi (X-Sandbox-Scenario): INSUFFICIENT_BALANCE (402) · NOT_FOUND (404) · OUT_OF_STOCK (409) · DOMAIN_IN_USE (409) · PRICE_CHANGED (409) · IDEMPOTENCY_PENDING (409) · RATE_LIMITED (429) · BUSY (429) · SERVICE_DISABLED (503) · FAILED (400) · PROVISION_FAILED (lệnh vẫn nhận, info về sau báo failed).

Yêu cầu
curl -X POST 'https://cloudmoon.net/api/v1/hosting/buy' \
  -H 'X-API-Key: ak_...' \
  -H 'Idempotency-Key: 7f9c2e4b-1a2b-4c3d-9e8f-0123456789ab' \
  -H 'Content-Type: application/json' \
  -d '{"product_id":1,"billing_cycle":"onemonth","domain":"khachhang.com"}'
Yêu cầu
import uuid
import requests

r = requests.post(
    "https://cloudmoon.net/api/v1/hosting/buy",
    headers={"X-API-Key": "ak_...", "Idempotency-Key": str(uuid.uuid4())},
    json={"product_id": 1, "billing_cycle": "onemonth", "domain": "khachhang.com"},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs
import { randomUUID } from "node:crypto";

const res = await fetch("https://cloudmoon.net/api/v1/hosting/buy", {
  method: "POST",
  headers: {
    "X-API-Key": "ak_...",
    "Content-Type": "application/json",
    "Idempotency-Key": randomUUID(),
  },
  body: JSON.stringify({ product_id: 1, billing_cycle: "onemonth", domain: "khachhang.com" }),
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('POST', '/v1/hosting/buy', ['product_id' => 1, 'billing_cycle' => 'onemonth', 'domain' => 'khachhang.com'], bin2hex(random_bytes(16)));
print_r($kq);
Thân yêu cầu
{
    "product_id": 1,
    "billing_cycle": "onemonth",
    "domain": "khachhang.com"
}
Phản hồi
{
    "status": "success",
    "msg": "Đã tạo hosting",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "domain": "khachhang.com",
        "provision_status": "ready",
        "charged": true,
        "product_id": 1,
        "billing_cycle": "onemonth",
        "price_buy": 50000,
        "time_expire": "2026-11-12",
        "panel": {
            "url": "https://panel.example.com:17777",
            "server_ip": "203.0.113.10",
            "username": "cm042a1b2c",
            "password": "Xy7kP2mQ9rT4vW1z",
            "ready_at": "2026-10-12T21:01:30+07:00"
        },
        "website_verified": true,
        "note": "Mật khẩu panel đọc lại được ở GET /hosting/info hoặc /hosting/credentials (khoá toàn quyền) — trỏ bản ghi A của tên miền về panel.server_ip"
    }
}
GET

/hosting/list

Chỉ đọc

Mọi hosting của tài khoản (không kèm mật khẩu), mỗi đơn kèm provision_status, gói, hạn mức, số liệu sử dụng, billing, allowed_actions. Mặc định bỏ đơn đã xoá; ?status= active | pending_expired | expired | deleted. Phân trang.

GET https://cloudmoon.net/api/v1/hosting/list
Tham sốVị tríBắt buộcMô tả
status query không Lọc theo trạng thái đơn
limit query không 1-200, mặc định 50
page query không Trang, tính từ 1
Yêu cầu
curl 'https://cloudmoon.net/api/v1/hosting/list' \
  -H 'X-API-Key: ak_...'
Yêu cầu
import requests

r = requests.get(
    "https://cloudmoon.net/api/v1/hosting/list",
    headers={"X-API-Key": "ak_..."},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/list", {
  headers: { "X-API-Key": "ak_..." },
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('GET', '/v1/hosting/list');
print_r($kq);
Phản hồi
{
    "status": "success",
    "msg": "OK",
    "data": {
        "items": [
            {
                "order_code": "121026HOSTA1B2C3D4E5F6",
                "name": "khachhang.com",
                "domain": "khachhang.com",
                "plan": {
                    "product_id": 1,
                    "name": "Hosting Starter",
                    "group_code": "vn50",
                    "region_code": "VN"
                },
                "quota": {
                    "disk_mb": 5120,
                    "bandwidth_mb": 0,
                    "email": 5,
                    "database": 0,
                    "websites": 1
                },
                "usage": {
                    "disk_mb": 120,
                    "bandwidth_mb": 500,
                    "synced_at": "2026-10-12T21:17:02+07:00"
                },
                "order_status": "active",
                "account_status": "active",
                "provision_status": "ready",
                "billing": {
                    "price_buy": 50000,
                    "price_renew": 50000,
                    "billing_cycle": "onemonth",
                    "renew_auto": "on",
                    "time_buy": "2026-10-12",
                    "time_expire": "2026-11-12"
                },
                "marketplace": false,
                "panel": {
                    "url": "https://panel.example.com:17777",
                    "server_ip": "203.0.113.10",
                    "username": "cm042a1b2c",
                    "ready_at": "2026-10-12T21:01:30+07:00"
                },
                "features": {
                    "renew": true,
                    "auto_renew": true,
                    "change_password": true,
                    "upgrade": true,
                    "change_cycle": true,
                    "delete": true,
                    "migrate": false,
                    "transfer": false
                },
                "allowed_actions": [
                    "renew",
                    "auto_renew",
                    "change_password",
                    "upgrade",
                    "change_cycle",
                    "delete"
                ]
            }
        ],
        "page": 1,
        "limit": 50,
        "total": 1
    }
}
GET

/hosting/info

Chỉ đọc

Chi tiết một hosting: provision_status (ready · provisioning · failed · expired · deleted), order_status / account_status (tạm ngưng vì quá hạn · bị khoá), gói + hạn mức, usage (số máy chủ đẩy về mỗi giờ — usage.synced_at), billing (price_renew = giá gia hạn kỳ tới), renew_until (hạn mới nếu gia hạn), refunded_amount (đơn bị huỷ), features + allowed_actions. panel.password CHỈ kèm khi khoá TOÀN QUYỀN, hosting ready và đang hoạt động.

GET https://cloudmoon.net/api/v1/hosting/info
Tham sốVị tríBắt buộcMô tả
order_code query có Mã đơn (order_code) — lấy từ lệnh mua hoặc /list

Chạy thử Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu.

Yêu cầu
curl 'https://cloudmoon.net/api/v1/hosting/info?order_code=121026HOSTA1B2C3D4E5F6' \
  -H 'X-API-Key: ak_...'
Yêu cầu
import requests

r = requests.get(
    "https://cloudmoon.net/api/v1/hosting/info",
    headers={"X-API-Key": "ak_..."},
    params={"order_code": "121026HOSTA1B2C3D4E5F6"},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/info?order_code=121026HOSTA1B2C3D4E5F6", {
  headers: { "X-API-Key": "ak_..." },
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('GET', '/v1/hosting/info?order_code=121026HOSTA1B2C3D4E5F6');
print_r($kq);
Phản hồi
{
    "status": "success",
    "msg": "OK",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "name": "khachhang.com",
        "domain": "khachhang.com",
        "plan": {
            "product_id": 1,
            "name": "Hosting Starter",
            "group_code": "vn50",
            "region_code": "VN"
        },
        "quota": {
            "disk_mb": 5120,
            "bandwidth_mb": 0,
            "email": 5,
            "database": 0,
            "websites": 1
        },
        "usage": {
            "disk_mb": 120,
            "bandwidth_mb": 500,
            "synced_at": "2026-10-12T21:17:02+07:00"
        },
        "order_status": "active",
        "account_status": "active",
        "provision_status": "ready",
        "billing": {
            "price_buy": 50000,
            "price_renew": 50000,
            "billing_cycle": "onemonth",
            "renew_auto": "on",
            "time_buy": "2026-10-12",
            "time_expire": "2026-11-12"
        },
        "marketplace": false,
        "panel": {
            "url": "https://panel.example.com:17777",
            "server_ip": "203.0.113.10",
            "username": "cm042a1b2c",
            "ready_at": "2026-10-12T21:01:30+07:00",
            "password": "Xy7kP2mQ9rT4vW1z"
        },
        "features": {
            "renew": true,
            "auto_renew": true,
            "change_password": true,
            "upgrade": true,
            "change_cycle": true,
            "delete": true,
            "migrate": false,
            "transfer": false
        },
        "refunded_amount": null,
        "renew_until": "2026-12-12",
        "allowed_actions": [
            "renew",
            "auto_renew",
            "change_password",
            "upgrade",
            "change_cycle",
            "delete"
        ]
    }
}
POST

/hosting/renew

Toàn quyền

Gia hạn một chu kỳ, trừ ví ngay. Giá = GIÁ GHI TRÊN ĐƠN (billing.price_renew) — báo giá trước bằng /hosting/quote {order_code, type: renew}. Hosting tạm ngưng vì quá hạn gia hạn được — gia hạn xong hệ thống mở lại hosting (mở lại chưa xong vì máy chủ bảo trì / trục trặc thì bộ phận kỹ thuật xử lý tiếp; bị bộ phận hỗ trợ khoá thì gia hạn được nhưng không tự mở khoá); đơn đang hoàn tất khởi tạo · đã huỷ · hết hạn hẳn · đã xoá bị chối. Máy chủ bảo trì vẫn gia hạn được. Nhịp: 60 giây/đơn (chung với nâng gói · đổi chu kỳ).

POST https://cloudmoon.net/api/v1/hosting/renew
Tham sốVị tríBắt buộcMô tả
Idempotency-Key header không chống trừ tiền hai lần khi gửi lại
order_code body có Mã đơn (order_code) — lấy từ lệnh mua hoặc /list

Chạy thử Gửi kèm X-Sandbox: 1: máy chủ kiểm như lượt thật rồi trả kết quả mô phỏng cùng khuôn — không trừ tiền, không đổi gì. Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu. Kịch bản lỗi (X-Sandbox-Scenario): INSUFFICIENT_BALANCE (402) · REBUILDING (409) · MIGRATING (409) · ORDER_EXPIRED (409) · ORDER_DELETED (409) · ORDER_CANCELLED (409) · IDEMPOTENCY_PENDING (409) · COOLDOWN (429) · IN_PROGRESS (429) · BUSY (429) · NOT_SUPPORTED (400) · FAILED (400).

Yêu cầu
curl -X POST 'https://cloudmoon.net/api/v1/hosting/renew' \
  -H 'X-API-Key: ak_...' \
  -H 'Idempotency-Key: 7f9c2e4b-1a2b-4c3d-9e8f-0123456789ab' \
  -H 'Content-Type: application/json' \
  -d '{"order_code":"121026HOSTA1B2C3D4E5F6"}'
Yêu cầu
import uuid
import requests

r = requests.post(
    "https://cloudmoon.net/api/v1/hosting/renew",
    headers={"X-API-Key": "ak_...", "Idempotency-Key": str(uuid.uuid4())},
    json={"order_code": "121026HOSTA1B2C3D4E5F6"},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs
import { randomUUID } from "node:crypto";

const res = await fetch("https://cloudmoon.net/api/v1/hosting/renew", {
  method: "POST",
  headers: {
    "X-API-Key": "ak_...",
    "Content-Type": "application/json",
    "Idempotency-Key": randomUUID(),
  },
  body: JSON.stringify({ order_code: "121026HOSTA1B2C3D4E5F6" }),
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('POST', '/v1/hosting/renew', ['order_code' => '121026HOSTA1B2C3D4E5F6'], bin2hex(random_bytes(16)));
print_r($kq);
Thân yêu cầu
{
    "order_code": "121026HOSTA1B2C3D4E5F6"
}
Phản hồi
{
    "status": "success",
    "msg": "Đã gia hạn",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "amount": 50000,
        "billing_cycle": "onemonth",
        "time_expire": "2026-12-12"
    }
}
POST

/hosting/auto-renew

Toàn quyền

Bật/tắt tự gia hạn (tới hạn hệ thống tự trừ ví theo giá ghi trên đơn). ĐẶT giá trị — gửi lại cùng lệnh không lật ngược; đặt đúng giá trị đang có vẫn thành công.

POST https://cloudmoon.net/api/v1/hosting/auto-renew
Tham sốVị tríBắt buộcMô tả
order_code body có Mã đơn (order_code) — lấy từ lệnh mua hoặc /list
enabled body có true | false (boolean JSON)

Chạy thử Gửi kèm X-Sandbox: 1: máy chủ kiểm như lượt thật rồi trả kết quả mô phỏng cùng khuôn — không trừ tiền, không đổi gì. Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu. Kịch bản lỗi (X-Sandbox-Scenario): ORDER_EXPIRED (409) · ORDER_DELETED (409) · ORDER_CANCELLED (409) · COOLDOWN (429) · IN_PROGRESS (429) · FAILED (400).

Yêu cầu
curl -X POST 'https://cloudmoon.net/api/v1/hosting/auto-renew' \
  -H 'X-API-Key: ak_...' \
  -H 'Content-Type: application/json' \
  -d '{"order_code":"121026HOSTA1B2C3D4E5F6","enabled":false}'
Yêu cầu
import requests

r = requests.post(
    "https://cloudmoon.net/api/v1/hosting/auto-renew",
    headers={"X-API-Key": "ak_..."},
    json={"order_code": "121026HOSTA1B2C3D4E5F6", "enabled": False},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/auto-renew", {
  method: "POST",
  headers: {
    "X-API-Key": "ak_...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ order_code: "121026HOSTA1B2C3D4E5F6", enabled: false }),
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('POST', '/v1/hosting/auto-renew', ['order_code' => '121026HOSTA1B2C3D4E5F6', 'enabled' => false]);
print_r($kq);
Thân yêu cầu
{
    "order_code": "121026HOSTA1B2C3D4E5F6",
    "enabled": false
}
Phản hồi
{
    "status": "success",
    "msg": "Đã tắt tự gia hạn",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "renew_auto": "off"
    }
}
POST

/hosting/change-password

Toàn quyền

Đổi mật khẩu panel; bỏ trống new_password ⇒ hệ thống sinh 16 ký tự. Luật: 8–64 ký tự, chỉ chữ · số · !@#$%^&*._- . Mật khẩu mới có trong câu trả lời (đọc lại được ở /hosting/info · /hosting/credentials, khoá toàn quyền). Chỉ hosting đang hoạt động; máy chủ bảo trì ⇒ 503 MAINTENANCE. Nhịp: 60 giây/đơn.

POST https://cloudmoon.net/api/v1/hosting/change-password
Tham sốVị tríBắt buộcMô tả
order_code body có Mã đơn (order_code) — lấy từ lệnh mua hoặc /list
new_password body không để trống = hệ thống sinh

Chạy thử Gửi kèm X-Sandbox: 1: máy chủ kiểm như lượt thật rồi trả kết quả mô phỏng cùng khuôn — không trừ tiền, không đổi gì. Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu. Kịch bản lỗi (X-Sandbox-Scenario): ORDER_EXPIRED (409) · ORDER_DELETED (409) · ORDER_CANCELLED (409) · RENEW_REQUIRED (409) · SUSPENDED (409) · REBUILDING (409) · MIGRATING (409) · MAINTENANCE (503) · COOLDOWN (429) · IN_PROGRESS (429) · BUSY (429) · FAILED (400).

Yêu cầu
curl -X POST 'https://cloudmoon.net/api/v1/hosting/change-password' \
  -H 'X-API-Key: ak_...' \
  -H 'Content-Type: application/json' \
  -d '{"order_code":"121026HOSTA1B2C3D4E5F6"}'
Yêu cầu
import requests

r = requests.post(
    "https://cloudmoon.net/api/v1/hosting/change-password",
    headers={"X-API-Key": "ak_..."},
    json={"order_code": "121026HOSTA1B2C3D4E5F6"},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/change-password", {
  method: "POST",
  headers: {
    "X-API-Key": "ak_...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ order_code: "121026HOSTA1B2C3D4E5F6" }),
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('POST', '/v1/hosting/change-password', ['order_code' => '121026HOSTA1B2C3D4E5F6']);
print_r($kq);
Thân yêu cầu
{
    "order_code": "121026HOSTA1B2C3D4E5F6"
}
Phản hồi
{
    "status": "success",
    "msg": "Đã đổi mật khẩu",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "username": "cm042a1b2c",
        "password": "Qw3eR5tY7uI9oP1a"
    }
}
POST

/hosting/upgrade

Toàn quyền

Nâng gói (giữ chu kỳ), trừ ví ngay. Chỉ lên gói CÙNG NHÓM, dung lượng không nhỏ hơn, còn hàng. Phí = max(0, giá kỳ gói mới − giá đang trả) × số kỳ còn lại (tối thiểu 1) — báo giá trước bằng /hosting/quote {order_code, type: upgrade, product_id}. Máy chủ hiện tại hết chỗ ⇒ 409 CAPACITY_UNAVAILABLE (chuyển máy chủ chỉ làm trên web). applied_on_server: false = đã thu tiền + đổi gói, máy chủ đang được áp gói mới.

POST https://cloudmoon.net/api/v1/hosting/upgrade
Tham sốVị tríBắt buộcMô tả
Idempotency-Key header không chống trừ tiền hai lần khi gửi lại
order_code body có Mã đơn (order_code) — lấy từ lệnh mua hoặc /list
product_id body có gói mới (cùng nhóm, trong /hosting/products)

Chạy thử Gửi kèm X-Sandbox: 1: máy chủ kiểm như lượt thật rồi trả kết quả mô phỏng cùng khuôn — không trừ tiền, không đổi gì. Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu. Kịch bản lỗi (X-Sandbox-Scenario): INSUFFICIENT_BALANCE (402) · NOT_FOUND (404) · OUT_OF_STOCK (409) · CAPACITY_UNAVAILABLE (409) · LISTED_ON_MARKETPLACE (409) · RENEW_REQUIRED (409) · SUSPENDED (409) · REBUILDING (409) · MIGRATING (409) · ORDER_EXPIRED (409) · ORDER_DELETED (409) · ORDER_CANCELLED (409) · IDEMPOTENCY_PENDING (409) · MAINTENANCE (503) · COOLDOWN (429) · IN_PROGRESS (429) · BUSY (429) · NOT_SUPPORTED (400) · FAILED (400).

Yêu cầu
curl -X POST 'https://cloudmoon.net/api/v1/hosting/upgrade' \
  -H 'X-API-Key: ak_...' \
  -H 'Idempotency-Key: 7f9c2e4b-1a2b-4c3d-9e8f-0123456789ab' \
  -H 'Content-Type: application/json' \
  -d '{"order_code":"121026HOSTA1B2C3D4E5F6","product_id":2}'
Yêu cầu
import uuid
import requests

r = requests.post(
    "https://cloudmoon.net/api/v1/hosting/upgrade",
    headers={"X-API-Key": "ak_...", "Idempotency-Key": str(uuid.uuid4())},
    json={"order_code": "121026HOSTA1B2C3D4E5F6", "product_id": 2},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs
import { randomUUID } from "node:crypto";

const res = await fetch("https://cloudmoon.net/api/v1/hosting/upgrade", {
  method: "POST",
  headers: {
    "X-API-Key": "ak_...",
    "Content-Type": "application/json",
    "Idempotency-Key": randomUUID(),
  },
  body: JSON.stringify({ order_code: "121026HOSTA1B2C3D4E5F6", product_id: 2 }),
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('POST', '/v1/hosting/upgrade', ['order_code' => '121026HOSTA1B2C3D4E5F6', 'product_id' => 2], bin2hex(random_bytes(16)));
print_r($kq);
Thân yêu cầu
{
    "order_code": "121026HOSTA1B2C3D4E5F6",
    "product_id": 2
}
Phản hồi
{
    "status": "success",
    "msg": "Đã nâng gói",
    "data": {
        "type": "upgrade",
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "product_id": 2,
        "plan_name": "Hosting Pro",
        "billing_cycle": "onemonth",
        "amount": 50000,
        "cycles_needed": 1,
        "days_left": 31,
        "price_renew": 100000,
        "applied_on_server": true
    }
}
POST

/hosting/change-cycle

Toàn quyền

Đổi chu kỳ thanh toán (giữ gói) — KHÔNG thu tiền ngay, giá kỳ mới áp từ lần gia hạn kế tiếp. Chỉ sang chu kỳ ĐANG BÁN và DÀI HƠN chu kỳ hiện tại.

POST https://cloudmoon.net/api/v1/hosting/change-cycle
Tham sốVị tríBắt buộcMô tả
order_code body có Mã đơn (order_code) — lấy từ lệnh mua hoặc /list
billing_cycle body có chu kỳ mới (dài hơn)

Chạy thử Gửi kèm X-Sandbox: 1: máy chủ kiểm như lượt thật rồi trả kết quả mô phỏng cùng khuôn — không trừ tiền, không đổi gì. Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu. Kịch bản lỗi (X-Sandbox-Scenario): LISTED_ON_MARKETPLACE (409) · RENEW_REQUIRED (409) · SUSPENDED (409) · REBUILDING (409) · MIGRATING (409) · ORDER_EXPIRED (409) · ORDER_DELETED (409) · ORDER_CANCELLED (409) · COOLDOWN (429) · IN_PROGRESS (429) · BUSY (429) · NOT_SUPPORTED (400) · FAILED (400).

Yêu cầu
curl -X POST 'https://cloudmoon.net/api/v1/hosting/change-cycle' \
  -H 'X-API-Key: ak_...' \
  -H 'Content-Type: application/json' \
  -d '{"order_code":"121026HOSTA1B2C3D4E5F6","billing_cycle":"threemonth"}'
Yêu cầu
import requests

r = requests.post(
    "https://cloudmoon.net/api/v1/hosting/change-cycle",
    headers={"X-API-Key": "ak_..."},
    json={"order_code": "121026HOSTA1B2C3D4E5F6", "billing_cycle": "threemonth"},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/change-cycle", {
  method: "POST",
  headers: {
    "X-API-Key": "ak_...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ order_code: "121026HOSTA1B2C3D4E5F6", billing_cycle: "threemonth" }),
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('POST', '/v1/hosting/change-cycle', ['order_code' => '121026HOSTA1B2C3D4E5F6', 'billing_cycle' => 'threemonth']);
print_r($kq);
Thân yêu cầu
{
    "order_code": "121026HOSTA1B2C3D4E5F6",
    "billing_cycle": "threemonth"
}
Phản hồi
{
    "status": "success",
    "msg": "Đã đổi chu kỳ (áp dụng từ lần gia hạn kế tiếp)",
    "data": {
        "type": "change_cycle",
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "product_id": 1,
        "plan_name": "Hosting Starter",
        "billing_cycle": "threemonth",
        "amount": 0,
        "cycles_needed": 0,
        "days_left": 31,
        "price_renew": 140000,
        "applied_on_server": true
    }
}
POST

/hosting/delete

Toàn quyền

Xoá hosting (website + tài khoản panel) — KHÔNG hoàn tiền, không khôi phục. Bắt buộc confirm = đúng order_code. Đơn đang rao trên chợ / đang chuyển máy / đang hoàn tất khởi tạo bị chối.

POST https://cloudmoon.net/api/v1/hosting/delete
Tham sốVị tríBắt buộcMô tả
order_code body có Mã đơn (order_code) — lấy từ lệnh mua hoặc /list
confirm body có gõ lại đúng order_code

Chạy thử Gửi kèm X-Sandbox: 1: máy chủ kiểm như lượt thật rồi trả kết quả mô phỏng cùng khuôn — không trừ tiền, không đổi gì. Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu. Kịch bản lỗi (X-Sandbox-Scenario): ORDER_DELETED (409) · ORDER_CANCELLED (409) · ORDER_EXPIRED (409) · REBUILDING (409) · MIGRATING (409) · SUSPENDED (409) · LISTED_ON_MARKETPLACE (409) · MAINTENANCE (503) · IN_PROGRESS (429) · BUSY (429) · FAILED (400).

Yêu cầu
curl -X POST 'https://cloudmoon.net/api/v1/hosting/delete' \
  -H 'X-API-Key: ak_...' \
  -H 'Content-Type: application/json' \
  -d '{"order_code":"121026HOSTA1B2C3D4E5F6","confirm":"121026HOSTA1B2C3D4E5F6"}'
Yêu cầu
import requests

r = requests.post(
    "https://cloudmoon.net/api/v1/hosting/delete",
    headers={"X-API-Key": "ak_..."},
    json={"order_code": "121026HOSTA1B2C3D4E5F6", "confirm": "121026HOSTA1B2C3D4E5F6"},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/delete", {
  method: "POST",
  headers: {
    "X-API-Key": "ak_...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ order_code: "121026HOSTA1B2C3D4E5F6", confirm: "121026HOSTA1B2C3D4E5F6" }),
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('POST', '/v1/hosting/delete', ['order_code' => '121026HOSTA1B2C3D4E5F6', 'confirm' => '121026HOSTA1B2C3D4E5F6']);
print_r($kq);
Thân yêu cầu
{
    "order_code": "121026HOSTA1B2C3D4E5F6",
    "confirm": "121026HOSTA1B2C3D4E5F6"
}
Phản hồi
{
    "status": "success",
    "msg": "Đã xoá hosting",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "order_status": "expired",
        "account_status": "deleted",
        "provision_status": "deleted",
        "refunded": false
    }
}
GET

/hosting/usage

Chỉ đọc

Dung lượng + băng thông đang dùng và hạn mức của gói (0 = không giới hạn). Số do máy chủ đẩy về mỗi giờ (synced_at); stale: true = quá 2 giờ chưa có số mới.

GET https://cloudmoon.net/api/v1/hosting/usage
Tham sốVị tríBắt buộcMô tả
order_code query có Mã đơn (order_code) — lấy từ lệnh mua hoặc /list

Chạy thử Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu.

Yêu cầu
curl 'https://cloudmoon.net/api/v1/hosting/usage?order_code=121026HOSTA1B2C3D4E5F6' \
  -H 'X-API-Key: ak_...'
Yêu cầu
import requests

r = requests.get(
    "https://cloudmoon.net/api/v1/hosting/usage",
    headers={"X-API-Key": "ak_..."},
    params={"order_code": "121026HOSTA1B2C3D4E5F6"},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/usage?order_code=121026HOSTA1B2C3D4E5F6", {
  headers: { "X-API-Key": "ak_..." },
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('GET', '/v1/hosting/usage?order_code=121026HOSTA1B2C3D4E5F6');
print_r($kq);
Phản hồi
{
    "status": "success",
    "msg": "OK",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "disk_mb": 120,
        "bandwidth_mb": 500,
        "quota_disk_mb": 5120,
        "quota_bandwidth_mb": 0,
        "synced_at": "2026-10-12T21:17:02+07:00",
        "stale": false
    }
}
GET

/hosting/credentials

Toàn quyền

Thông tin đăng nhập panel (url · server_ip · username · password) — khoá TOÀN QUYỀN, chỉ hosting ready và đang hoạt động (cùng luật panel.password của /hosting/info).

GET https://cloudmoon.net/api/v1/hosting/credentials
Tham sốVị tríBắt buộcMô tả
order_code query có Mã đơn (order_code) — lấy từ lệnh mua hoặc /list

Chạy thử Nhận cả mã SANDBOX… của lệnh mua chạy thử ⇒ trả máy mẫu.

Yêu cầu
curl 'https://cloudmoon.net/api/v1/hosting/credentials?order_code=121026HOSTA1B2C3D4E5F6' \
  -H 'X-API-Key: ak_...'
Yêu cầu
import requests

r = requests.get(
    "https://cloudmoon.net/api/v1/hosting/credentials",
    headers={"X-API-Key": "ak_..."},
    params={"order_code": "121026HOSTA1B2C3D4E5F6"},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/hosting/credentials?order_code=121026HOSTA1B2C3D4E5F6", {
  headers: { "X-API-Key": "ak_..." },
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('GET', '/v1/hosting/credentials?order_code=121026HOSTA1B2C3D4E5F6');
print_r($kq);
Phản hồi
{
    "status": "success",
    "msg": "OK",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "domain": "khachhang.com",
        "panel_url": "https://panel.example.com:17777",
        "server_ip": "203.0.113.10",
        "username": "cm042a1b2c",
        "password": "Xy7kP2mQ9rT4vW1z",
        "ready_at": "2026-10-12T21:01:30+07:00"
    }
}
Zalo