Vitamin API 参考
在你自己的网站、机器人或脚本里销售并管理 VPN 账号与虚拟服务器。
基础 URLhttps://apiservice.vitamindata.net/api/v1
密钥在你的面板中创建。如果看不到该栏目,请联系支持为你的账户开启 API 访问。
1在你的面板中创建 API 密钥,并在每次调用时作为 bearer token 发送。
2调用 Ping 验证密钥,然后用 ListPlans 和 GetVPSStorefront 拉取你的价格。
3用 FUNDING_AUTO 销售:余额够时从余额扣款,不够时你的客户会得到一个支付链接。
身份验证
每个请求都以 bearer token 的形式携带你的密钥。此主机上没有 cookie,也不需要获取 CSRF token —— 密钥就是全部凭据。
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
密钥在你面板的 API 栏目中创建。密钥内容只在创建时显示一次:我们只保存它的哈希。如果丢失,解决办法是轮换密钥 —— 轮换会签发新的密钥内容,并让旧的再工作一天,这样你可以不停机地完成部署。
一个密钥可以限定来源地址列表、拥有自己的每分钟速率限制,也可以被禁用某些具体操作。这些由我们的运营人员设置 —— 如果你需要一个例如可以购买但永远不能删除服务的密钥,请联系支持。
测试密钥
以 sk_test_ 开头的密钥会读取真实数据,但会拒绝任何花钱或触及真实机器的操作,这样你可以在集成还不可能产生费用之前把它接通并验证。
失败是什么样子
未知的密钥,和所属账户未开启 API 访问的密钥,会得到一字不差、完全相同的 401:响应绝不会确认某个密钥是否存在。例外是你自己那把已过轮换重叠期的密钥 —— 它会明说 api key expired,因为你已经知道那把密钥是真的,你需要知道的是它为什么不再工作。来自同一地址的反复失败会被限流 —— 参见速率限制。
付款方式
你购买的一切 —— VPN 账号、续期、服务器、服务器续费、升级 —— 都走同一套契约。由你选择如何付款:
funding | 会发生什么 |
|---|
FUNDING_AUTO | 推荐。余额够就从余额扣;不够时调用仍然成功,并给你一个支付链接。一次调用,没有需要解读的错误。 |
FUNDING_BALANCE | 仅使用余额。余额不足时调用会以 insufficient_balance 失败(错误里依然带着可支付的链接)。 |
FUNDING_INVOICE | 始终返回支付链接,即使你的余额本来足够。 |
使用 FUNDING_AUTO 时,你只需判断一个字段:
{"order": {...}, "paid": true, "status": "completed"}
{"order": {...}, "status": "payment_required",
"invoice": {"invoice_id": "inv_9m2r4t",
"pay_url": "https://pay.example.com/i/inv_9m2r4t",
"price_usd": "11.90", "expires_at": "1785499200"}}
completed 表示钱已扣除、交付已开始 —— 轮询 GetOrder 直到状态变为 delivered。payment_required 表示把客户引导到 pay_url;账单支付后交付会自动开始。
价格始终由我们决定。你可以发送 expected_total_usd 作为保护:如果我们最新的报价不同,这笔销售会以 price_changed 和新的总额被拒绝,而不是按客户从未看到的金额收费。
安全重试
每一个花钱的调用都请发送 Idempotency-Key 头。如果响应始终没有到达你 —— 超时、连接中断、进程重新部署 —— 用相同的键重发相同的请求,你会拿回最初的结果,而不是第二次扣款。
Idempotency-Key: 8f14e45f-ea6d-4b3a-9c1b-2f0d5a7e91c3
每个客户动作用一个新的键(UUID 最理想)。用同一个键搭配不同的请求体会以 idempotency_conflict 被拒绝 —— 这种组合意味着代码有 bug,猜测你想要哪一个请求比直接告知你更糟。
速率限制
每个已通过身份验证的响应都会告诉你,你这把密钥当前的额度状况:
RateLimit-Limit: 6000
RateLimit-Remaining: 5987
RateLimit-Policy: 6000;w=60
限制按密钥、按分钟计算,并针对你的账户设定 —— 默认值适合一个店面;繁忙的机器人应当申请更高的额度,而不是把自己压到默认值。超出后会返回带 Retry-After 的 429。
如果来自同一地址的大量请求身份验证失败,也会出现 429。那是暴力破解防护,不是你的配额:它会自动解除(响应头会说明何时),而一个正常的密钥永远不会触发它。
你还会在每个响应上看到一组 X-Ratelimit-* 头,包括不带密钥的响应。那是整个 API 前面一道粗粒度的按地址限速闸,不是你这把密钥的配额 —— 请按 RateLimit-Remaining 控制节奏,把 X- 开头的那些头当作与你无关。
错误
失败以一个 HTTP 状态码加一个 JSON 响应体的形式返回。顶层 code 是传输层分类;顶层 message 携带稳定的机器码。完整细节 —— 同一个机器码、一句可安全展示的描述,以及任何可据以行动的附加字段 —— 位于 details 中的 debug 之下:
{"code": "failed_precondition",
"message": "insufficient_balance",
"details": [{"type": "neopay.seller.publicapi.v1.ErrorInfo",
"value": "CgptZXNzYWdl…",
"debug": {"code": "insufficient_balance",
"message": "insufficient balance",
"payUrl": "https://pay.example.com/i/inv_9m2r4t",
"orderId": "ord_8c3d1e",
"totalUsd": "11.90"}}]}
错误通道有两个值得在代码里处理的怪癖:value 是 base64 编码的 protobuf(忽略它 —— 读 debug);而 debug 里的附加字段是 lowerCamelCase —— payUrl、orderId、totalUsd、retryAfterSeconds —— 这是 Connect 的约定,与其他地方的 snake_case 不同。请根据顶层的 message 或 debug.code 来分支;绝不要根据那句描述文字。
请求获得授权之前的拒绝
一个根本没走到处理逻辑的请求 —— 缺少密钥或密钥有误(401)、密钥不允许的来源地址(403)、触到速率限制(429)、身份验证服务中断(503)—— 会在入口处就被拒绝,而入口返回的响应体更短:只有一个传输层 code 和一句普通的描述文字,没有 details,也没有机器码。
{"code": "unauthenticated", "message": "invalid api key"}
所以对这些情况请按 HTTP 状态码分支(并遵守 Retry-After,429 会带上这个头);下面的机器码只属于已经走到处理逻辑的调用。那道粗粒度的按地址限速闸更老,它返回的是 {"error":"rate_limited"} —— 键名是 error,不是 code。
| 代码 | 含义 | 该怎么做 |
|---|
forbidden_scope | 密钥没有此调用所需的权限,或者这个操作已被禁用。 | 请联系支持扩大密钥的权限。 |
not_found | 在此账户下没有这个对象。 | 检查 id。属于他人的 id 也会得到同样的响应 —— 这是刻意设计。 |
invalid_request | 某个字段格式错误。 | 修正后重发;原样重试没有帮助。 |
insufficient_balance | 仅用余额付款不足以支付。 | 使用详情中的 payUrl,或改用 FUNDING_AUTO。 |
price_changed | 你的 expected_total_usd 已不再匹配。 | 重新报价,并与客户确认新的总额。 |
idempotency_conflict | 该键曾用于不同的请求体。 | 每个动作使用一个新的键。 |
sandbox_unavailable | 一个 sk_test_ 密钥试图花钱或触及真实机器。 | 这是预期行为 —— 该调用请用正式密钥。测试密钥只读,从不购买。 |
unpriceable | 你要的这套配置无法售卖 —— 未定价的套餐或节点,或者没有任何定价模型覆盖的购物车。 | 购买之前重新读取店面并报价;同样的购物车在报价时也会被拒绝。 |
upstream_unavailable | 我们依赖的某个系统当前不可用。 | 按退避策略重试;读取的数据可能短时间偏旧。 |
order_failed | 付款之后交付失败。 | 不要重新购买。轮询 GetOrder;我们会自动补救这类订单,支持也能看到它。 |
internal | 我们这边出了故障,且未被归类。 | 按退避策略重试一次;如果反复出现,请把 X-Request-Id 提供给支持。 |
约定
- 传输方式。每个调用都是带 JSON 请求体的
POST {base}/{Method} —— POST /api/v1/CreateVPNOrder。除此之外什么都没有:其他任何 HTTP 方法都会得到 405,不存在 REST 动词映射,也没有路径参数。 - 金额是字符串。
"19.99",绝不是 19.99:JSON 数字在大多数语言里是浮点数,无法精确表示一分钱。 - 64 位整数以字符串形式到达。每个字节数和每个 unix 时间戳都是 64 位的,线路上会给它们加引号 ——
"remaining_bytes": "96636764160"。请把它们解析为整数;在请求中两种形式都可以发送。 - 零值会被省略。值为
0、false 或为空的字段根本不会出现在响应中。把缺失当作零 —— 并且记住,每日上限为 0 表示没有上限,而不是“0 GB”。 - 时间是 unix 秒,唯一的例外是交易查询窗口,它接受并返回 RFC3339 或
YYYY-MM-DD。 - 流量一律以字节计,任何数字都绝不是 GB。
- id 是不透明的。
acc_…、ord_…、vpn_…。永远不要解析或自行生成 id,也不要假定它们是连续的。 - 分页使用不透明游标:把上一次响应的
next_cursor 传回来。next_cursor 为空表示你已经取完了。 - 字段表使用简短的类型标记。
money —— 精确的十进制字符串;unix —— unix 秒(64 位,因此是字符串);bytes —— 字节数(64 位,因此是字符串);int64 —— 其他任何 64 位整数(字符串);int —— 32 位,普通数字;cursor —— 不透明的分页句柄;enum —— 所列值中的恰好一个。 - 新字段会在没有通知的情况下出现,而已有字段的含义不会改变。忽略你不认识的内容。
开始
第一个要调用的接口:它证明密钥可用,并告诉你它属于哪个账户。
https://apiservice.vitamindata.net/api/v1/Ping返回你的账户 id、密钥是正式的还是测试的,以及我们的时间。
请求
请求示例curl https://apiservice.vitamindata.net/api/v1/Ping \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{}'
响应200 · application/json
account_idstring
密钥所属的账户 —— 证明密钥已被识别。
modeenum
你发送的是哪种密钥。
取值之一:livetest
server_timeunix
我们的时间 —— 便于在时钟漂移弄坏签名或时间窗口之前发现它。
响应示例{
"account_id": "acc_9f3k2m7q",
"mode": "live",
"server_time": "1785412800"
}
账户与余额
https://apiservice.vitamindata.net/api/v1/GetAccount你账户的邮箱、状态、语言,以及邮箱是否已验证。
请求
请求示例curl https://apiservice.vitamindata.net/api/v1/GetAccount \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{}'
响应200 · application/json
account.account_idstring
公开 id(acc_…)。
account.emailstring
登录邮箱地址。
account.statusstring
除非账户受限,否则为 active。
account.localestring
账户的语言 —— 卡片名称和通知都会按它本地化。
account.email_verifiedbool
邮箱地址已通过验证。
account.created_atunix
账户的创建时间。
响应示例{
"account": {
"account_id": "acc_9f3k2m7q",
"email": "dev@example.com",
"status": "active",
"locale": "en",
"email_verified": true,
"created_at": "1769000000"
}
}
https://apiservice.vitamindata.net/api/v1/GetBalance你的账本余额,以及一次购买实际可动用的金额。
available_usd 才是购买前要看的数字 —— 它不包含已被进行中的订单锁定的金额。
请求
请求示例curl https://apiservice.vitamindata.net/api/v1/GetBalance \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{}'
响应200 · application/json
available_usdmoney
余额减去锁定 —— 一次购买此刻实际能花的金额。
as_ofstring
这些数字对应的账本时间戳,RFC3339。
响应示例{
"balance_usd": "72.60",
"available_usd": "60.70",
"as_of": "2026-07-29T12:00:00Z"
}
https://apiservice.vitamindata.net/api/v1/ListTransactions你的账本,最新的在前。
默认最近三个月。超过 92 天的范围会被收窄,响应会告诉你它实际使用的范围 —— 所以短的结果绝不会含糊。
请求
limitint可选
页大小。默认 25,最大 100。
cursorcursor可选
上一次响应的 next_cursor。第一页时省略。
kindstring可选
可选过滤器,逗号分隔,取值为下方列出的 kind 值。
fromstring可选
窗口起点,RFC3339 或 YYYY-MM-DD。
tostring可选
窗口终点。只有日期的 to 包含那一整天。
请求示例curl https://apiservice.vitamindata.net/api/v1/ListTransactions \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"limit":25,"cursor":"","kind":"topup_credit,invoice_debit_reserved","from":"2026-05-01","to":"2026-07-30"}'
响应200 · application/json
transactions[].idstring
账本行的 id。
transactions[].tsstring
时间,RFC3339。
transactions[].kindenum
资金因何变动。topup_credit 是已支付的充值;两种 invoice_debit_* 是购买。进行中的订单在内部锁定与释放资金的动作不属于这份流水。
取值之一:topup_creditexternal_creditinvoice_debit_reservedinvoice_debit_externaloverpay_creditmanual_creditmanual_debitspend_debitspend_refundautomated_correction
transactions[].amount_usdmoney
带符号 —— 扣款为负。
transactions[].balance_after_usdmoney
此行之后的滚动余额。
transactions[].ref_invoice_idstring
这笔变动背后的账单 —— 把它传给 GetInvoice 可获得完整来龙去脉。
transactions[].descriptionstring
简短的人类可读标签。仅供展示;绝不要据此分支。
next_cursorcursor
把它作为 cursor 传回以获取下一页。缺失/为空 = 已经取完。
fromstring
实际生效的窗口起点(RFC3339)。比你请求的更窄 ⇒ 你触到了 92 天上限。
响应示例{
"transactions": [
{"id": "tx_01j9zq", "ts": "2026-07-28T09:14:03Z", "kind": "invoice_debit_reserved",
"amount_usd": "-11.90", "balance_after_usd": "72.60",
"ref_invoice_id": "inv_5k8p2q", "description": "order ord_7b2c9d"},
{"id": "tx_01j8xw", "ts": "2026-07-25T18:40:11Z", "kind": "topup_credit",
"amount_usd": "50.00", "balance_after_usd": "84.50", "ref_invoice_id": "inv_3d1x8n"}
],
"from": "2026-04-30T00:00:00Z",
"to": "2026-07-29T23:59:59Z"
}
POST
CreateTopup
buyIdempotency-Key
https://apiservice.vitamindata.net/api/v1/CreateTopup创建一张可支付的账单,用于为你的余额充值。
把客户(或你自己)引导到 invoice.pay_url。余额在支付后变动。
请求
amount_usdmoney必填
要充值多少,十进制字符串。
请求示例curl https://apiservice.vitamindata.net/api/v1/CreateTopup \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"amount_usd":"50.00"}'
响应200 · application/json
invoice.invoice_idstring
网关的账单 id(inv_…)。
invoice.statusenum
pending 表示可支付。从 confirmed 到 delivered_redirected 的所有状态都表示钱已不可逆地到账 —— 把它们全部当作已支付。expired 表示链接在未支付的情况下已失效。
取值之一:pendingconfirmedsweepingsweptdeliveringdelivereddelivered_redirectedexpired
invoice.pay_urlstring
托管的支付页面。把客户引导到这里;所有支付通道(币种、链、余额)都在它后面。
invoice.pay_telegram_urlstring
同一张账单,可在 Telegram 内支付:它会打开支付服务商自己的机器人,由机器人显示金额并在那里收款。把它放在 pay_url 旁边,供不愿离开应用的客户使用。可能缺失 —— 只有配置了机器人的支付服务商才有,所以绝不要把它当作你唯一的支付按钮。
invoice.price_usdmoney
账单收取的金额。
invoice.expires_atunix
支付窗口的关闭时间。
响应示例{
"invoice": {
"invoice_id": "inv_3d1x8n",
"status": "pending",
"pay_url": "https://pay.example.com/i/inv_3d1x8n",
"pay_telegram_url": "https://t.me/VitaminPayBot?start=3d1x8n",
"price_usd": "50.00",
"expires_at": "1785499200"
}
}
https://apiservice.vitamindata.net/api/v1/GetInvoice一笔支付的完整明细,包括链上所显示的内容。
账本行的 ref_invoice_id 就是关联键。只能读取你自己账户创建的账单。
请求
invoice_idstring必填
来自账本行的 ref_invoice_id、某个订单或某次充值。
请求示例curl https://apiservice.vitamindata.net/api/v1/GetInvoice \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"invoice_id":"inv_5k8p2q"}'
响应200 · application/json
invoice.invoice_idstring
网关的账单 id(inv_…)。
invoice.statusenum
pending 表示可支付。从 confirmed 到 delivered_redirected 的所有状态都表示钱已不可逆地到账 —— 把它们全部当作已支付。expired 表示链接在未支付的情况下已失效。
取值之一:pendingconfirmedsweepingsweptdeliveringdelivereddelivered_redirectedexpired
invoice.pay_urlstring
托管的支付页面。把客户引导到这里;所有支付通道(币种、链、余额)都在它后面。
invoice.pay_telegram_urlstring
同一张账单,可在 Telegram 内支付:它会打开支付服务商自己的机器人,由机器人显示金额并在那里收款。把它放在 pay_url 旁边,供不愿离开应用的客户使用。可能缺失 —— 只有配置了机器人的支付服务商才有,所以绝不要把它当作你唯一的支付按钮。
invoice.price_usdmoney
账单收取的金额。
invoice.expires_atunix
支付窗口的关闭时间。
paymentsarray
链上所显示的内容。余额支付的账单(不涉及链)以及尚无人支付的账单都为空 —— 空列表不是错误。
payments[].chainstring
付款到达的网络(tron、bsc 等)。
payments[].assetstring
支付所用的资产(USDT 等)。
payments[].amountmoney
资产数额,精确值。
payments[].tx_hashstring
链上交易 —— 你客户的付款凭证。
payments[].confirmedbool
链上已最终确认。
payments[].seen_atunix
我们首次观察到它的时间。
order_idstring
这张账单买了什么。充值时缺失,因为充值不购买任何东西。
响应示例{
"invoice": {
"invoice_id": "inv_5k8p2q",
"status": "confirmed",
"pay_url": "https://pay.example.com/i/inv_5k8p2q",
"price_usd": "11.90",
"expires_at": "1785499200"
},
"payments": [
{"chain": "tron", "asset": "USDT", "amount": "11.90",
"tx_hash": "c4a1f09e2b7d", "confirmed": true, "seen_at": "1785412920"}
],
"order_id": "ord_7b2c9d"
}
价格
这里的任何调用都不会创建任何东西 —— 在客户下决定之前,你可以随意反复报价。
https://apiservice.vitamindata.net/api/v1/ListPlans你可以销售的内容:滑块的上下限,以及如果你的店面使用固定价格卡片,也包括这些卡片。
哪一种有值就渲染哪一种。购买卡片的方式是把它的 bundle_id 放进购物车;滑块购物车使用 gb/月数/用户数。
请求
请求示例curl https://apiservice.vitamindata.net/api/v1/ListPlans \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{}'
响应200 · application/json
model_namestring
你店面的定价模型。
boundsobject
配置器的规则 —— 每次报价和下单都会在服务端重新校验。
bounds.gb_minint
购物车可请求的最小流量。
bounds.users_minint
最少并发设备数。
bounds.months_minint
最短期限。
bounds.new_accounts_maxint
单个订单最多可创建的账号数。
bounds.extend_maxint
单个订单最多可续期的账号数。
bounds.default_gbint
合理的滑块默认值。
bounds.default_usersint
默认设备数。
bounds.default_monthsint
默认期限。
bundlesarray
固定价格卡片(当你的店面是卡片目录时)。
bundles[].bundle_idstring
要放进 cart.bundle_id 的句柄。
bundles[].namestring
卡片名称,已按账户语言本地化。
bundles[].online_usersint
并发设备数。
bundles[].price_usdmoney
价格。它就是最终价格 —— 卡片无需报价。
bundles[].highlightbool
店面的主推卡片。
bundles[].daily_cap_gbint
每日上限,以 GB 计。缺失 = 没有。
响应示例{
"model_name": "vpn_dynamic",
"model_type": "dynamic_v2",
"bounds": {
"gb_min": 10, "gb_max": 500, "gb_step": 10,
"users_min": 1, "users_max": 10,
"months_min": 1, "months_max": 12,
"new_accounts_max": 5, "extend_max": 10,
"default_gb": 100, "default_users": 3, "default_months": 1
},
"bundles": [
{"bundle_id": "card_100_1m", "name": "100 GB · 1 month", "gb": 100, "months": 1,
"online_users": 3, "price_usd": "11.90", "highlight": true}
]
}
https://apiservice.vitamindata.net/api/v1/Quote一个 VPN 购物车的最终价格,逐项列出。折扣已经计算在内。
请求
cart.kindenum必填
购买新账号,或为已有账号增加流量和时长。
取值之一:newextend
cart.gbint可选
每个账号的流量,以 GB 计,须在 ListPlans 给出的边界内。
cart.monthsint可选
每个账号的有效期,以月计。
cart.usersint可选
每个账号的并发设备数。
cart.new_accountsint可选
仅限 kind:"new":要创建多少个账号。用户名由服务端生成。
cart.extend_vpn_idsarray可选
仅限 kind:"extend":要续期的账号,按公开 id。
cart.bundle_idstring可选
购买 ListPlans.bundles 中的固定价格卡片,而不是自行配置的购物车。设置后 gb/月数/用户数会被忽略 —— 以卡片自身的取值和价格为准。
请求示例curl https://apiservice.vitamindata.net/api/v1/Quote \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"cart":{"kind":"new","gb":100,"months":1,"users":3,"new_accounts":2}}'
此请求的其他形态为你已持有的账号续期{"cart":{"kind":"extend","gb":50,"months":1,"users":3,"extend_vpn_ids":["vpn_6t2k9p","vpn_1a4b7c"]}}
购买固定价格卡片,而不是自行配置购物车{"cart":{"kind":"new","bundle_id":"card_100_1m","new_accounts":1}}
响应200 · application/json
quoteobject
逐项列出的价格。不会创建任何东西,也不会收费。
quote.model_namestring
由哪个定价模型作答。
quote.model_typestring
该模型的引擎版本。
quote.base_usdmoney
折扣与附加费之前的价格。
quote.total_usdmoney
最终价格 —— 用这个购物车下单就收这么多。
quote.linesarray
逐项明细,带符号,加总恰好等于总额。
quote.lines[].codestring
这一行是什么(base、某个折扣码、某项附加费……)。
quote.lines[].kindstring
该行的类别,供你的 UI 分组。
quote.lines[].amount_usdmoney
带符号。折扣为负;各行加总恰好等于 total_usd。
quote.lines[].pctstring
该行背后的百分比(如果有)。
quote.cappedbool
总额触到了定价模型的上限。
quote.floor_appliedbool
总额被抬高到定价模型的下限。
quote.clampedenum
当购物车的某个取值在定价前被限制回边界内时设置。
取值之一:minmax
quote.invalidstring
非空表示该购物车无法定价 —— 把它展示出来,且绝不要按这样的报价收费。
quote.metamap
模型附加信息,string→string(例如升级的 remaining_days)。
响应示例{
"quote": {
"model_name": "vpn_dynamic",
"model_type": "dynamic_v2",
"base_usd": "14.00",
"total_usd": "11.90",
"lines": [
{"code": "base", "kind": "base", "amount_usd": "14.00"},
{"code": "loyalty", "kind": "discount", "amount_usd": "-2.10", "pct": "15"}
]
}
}
销售 VPN
POST
CreateVPNOrder
buyIdempotency-Key
https://apiservice.vitamindata.net/api/v1/CreateVPNOrder购买新的 VPN 账号,或为已有账号续期("kind":"extend" 配合 extend_vpn_ids)。
响应可能有两种形态,参见付款方式。
请求
cartobject必填
要买什么 —— 与 Quote 定价的形态相同。
cart.kindenum必填
购买新账号,或为已有账号增加流量和时长。
取值之一:newextend
cart.gbint可选
每个账号的流量,以 GB 计,须在 ListPlans 给出的边界内。
cart.monthsint可选
每个账号的有效期,以月计。
cart.usersint可选
每个账号的并发设备数。
cart.new_accountsint可选
仅限 kind:"new":要创建多少个账号。用户名由服务端生成。
cart.extend_vpn_idsarray可选
仅限 kind:"extend":要续期的账号,按公开 id。
cart.bundle_idstring可选
购买 ListPlans.bundles 中的固定价格卡片,而不是自行配置的购物车。设置后 gb/月数/用户数会被忽略 —— 以卡片自身的取值和价格为准。
fundingenum必填
如何付款 —— 参见付款方式。没有默认值:省略会被拒绝。
取值之一:FUNDING_AUTOFUNDING_BALANCEFUNDING_INVOICE
expected_total_usdmoney可选
确认保护。设置后,如果我们最新的报价与之不同,这笔销售会以 price_changed 被拒绝,而不是按客户从未见过的金额收费。
请求示例curl https://apiservice.vitamindata.net/api/v1/CreateVPNOrder \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"cart":{"kind":"new","gb":100,"months":1,"users":3,"new_accounts":1},"funding":"FUNDING_AUTO","expected_total_usd":"11.90"}'
此请求的其他形态为你已持有的账号续期{"cart":{"kind":"extend","gb":50,"months":1,"users":3,"extend_vpn_ids":["vpn_6t2k9p"]},"funding":"FUNDING_AUTO"}
购买固定价格卡片,从余额扣款{"cart":{"kind":"new","bundle_id":"card_100_1m","new_accounts":1},"funding":"FUNDING_BALANCE"}
响应200 · application/json
orderobject
订单 —— 轮询 GetOrder 直到状态变为 delivered。
order.order_idstring
订单的公开 id(ord_…)。
order.productenum
买的是什么。
取值之一:vpnvps
order.kindstring
购买的形式:new、extend、upgrade……
order.statusenum
生命周期。delivered 是目标;needs_operator 表示钱已到账、有人正在人工完成交付 —— 不要重新购买;expired 表示账单在未支付的情况下已过期。
取值之一:createdinvoicedpaiddeliveringdeliveredneeds_operatorfailedrefund_pendingrefundedexpired
order.fundingenum
实际使用了哪种付款方式。FUNDING_AUTO 最终会落到其中一种。
取值之一:invoicebalance
order.total_usdmoney
订单收取的金额。
order.invoice_idstring
订单背后的账单 —— 无论用哪种方式付款,每个订单都有一张。
order.itemsint
订单创建或续期多少个权益。
order.created_atunix
下单时间。
order.delivered_atunix
交付完成的时间。在那之前缺失。
order.breakdownobject
客户确认过的那份报价,原样保留 —— 与 Quote 返回的形态相同。
invoiceobject
订单背后的账单:payment_required 时可支付,completed 时已结清。
invoice.invoice_idstring
网关的账单 id(inv_…)。
invoice.statusenum
pending 表示可支付。从 confirmed 到 delivered_redirected 的所有状态都表示钱已不可逆地到账 —— 把它们全部当作已支付。expired 表示链接在未支付的情况下已失效。
取值之一:pendingconfirmedsweepingsweptdeliveringdelivereddelivered_redirectedexpired
invoice.pay_urlstring
托管的支付页面。把客户引导到这里;所有支付通道(币种、链、余额)都在它后面。
invoice.pay_telegram_urlstring
同一张账单,可在 Telegram 内支付:它会打开支付服务商自己的机器人,由机器人显示金额并在那里收款。把它放在 pay_url 旁边,供不愿离开应用的客户使用。可能缺失 —— 只有配置了机器人的支付服务商才有,所以绝不要把它当作你唯一的支付按钮。
invoice.price_usdmoney
账单收取的金额。
invoice.expires_atunix
支付窗口的关闭时间。
paidbool
钱已收讫。状态为 payment_required 时缺失(= false)。
statusenum
就靠这个字段来分支 —— 参见付款方式。
取值之一:completedpayment_required
响应示例{
"order": {
"order_id": "ord_8c3d1e", "product": "vpn", "kind": "new",
"status": "invoiced", "funding": "invoice", "total_usd": "11.90",
"invoice_id": "inv_9m2r4t", "items": 1, "created_at": "1785412800"
},
"invoice": {
"invoice_id": "inv_9m2r4t", "status": "pending",
"pay_url": "https://pay.example.com/i/inv_9m2r4t",
"pay_telegram_url": "https://t.me/VitaminPayBot?start=9m2r4t",
"price_usd": "11.90", "expires_at": "1785499200"
},
"status": "payment_required"
}
https://apiservice.vitamindata.net/api/v1/GetOrder购买之后轮询它:created → invoiced → paid → delivering → delivered。
请求
order_idstring必填
来自你所下的订单。
请求示例curl https://apiservice.vitamindata.net/api/v1/GetOrder \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"order_id":"ord_7b2c9d"}'
响应200 · application/json
order.order_idstring
订单的公开 id(ord_…)。
order.productenum
买的是什么。
取值之一:vpnvps
order.kindstring
购买的形式:new、extend、upgrade……
order.statusenum
生命周期。delivered 是目标;needs_operator 表示钱已到账、有人正在人工完成交付 —— 不要重新购买;expired 表示账单在未支付的情况下已过期。
取值之一:createdinvoicedpaiddeliveringdeliveredneeds_operatorfailedrefund_pendingrefundedexpired
order.fundingenum
实际使用了哪种付款方式。FUNDING_AUTO 最终会落到其中一种。
取值之一:invoicebalance
order.total_usdmoney
订单收取的金额。
order.invoice_idstring
订单背后的账单 —— 无论用哪种方式付款,每个订单都有一张。
order.itemsint
订单创建或续期多少个权益。
order.created_atunix
下单时间。
order.delivered_atunix
交付完成的时间。在那之前缺失。
order.breakdownobject
客户确认过的那份报价,原样保留 —— 与 Quote 返回的形态相同。
invoiceobject
仅在订单仍等待支付时填充 —— 形态与其他地方相同。
响应示例{
"order": {
"order_id": "ord_7b2c9d", "product": "vpn", "kind": "new",
"status": "delivered", "funding": "balance", "total_usd": "11.90",
"invoice_id": "inv_5k8p2q", "items": 1,
"created_at": "1785230043", "delivered_at": "1785230103",
"breakdown": {
"model_name": "vpn_dynamic",
"model_type": "dynamic_v2",
"base_usd": "14.00",
"total_usd": "11.90",
"lines": [
{"code": "base", "kind": "base", "amount_usd": "14.00"},
{"code": "loyalty", "kind": "discount", "amount_usd": "-2.10", "pct": "15"}
]
}
}
}
https://apiservice.vitamindata.net/api/v1/ListOrders你的订单历史,最新的在前。
请求
limitint可选
页大小。默认 25,最大 100。
cursorcursor可选
上一次响应的 next_cursor。第一页时省略。
请求示例curl https://apiservice.vitamindata.net/api/v1/ListOrders \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"limit":25,"cursor":""}'
响应200 · application/json
orders[].order_idstring
订单的公开 id(ord_…)。
orders[].productenum
买的是什么。
取值之一:vpnvps
orders[].kindstring
购买的形式:new、extend、upgrade……
orders[].statusenum
生命周期。delivered 是目标;needs_operator 表示钱已到账、有人正在人工完成交付 —— 不要重新购买;expired 表示账单在未支付的情况下已过期。
取值之一:createdinvoicedpaiddeliveringdeliveredneeds_operatorfailedrefund_pendingrefundedexpired
orders[].fundingenum
实际使用了哪种付款方式。FUNDING_AUTO 最终会落到其中一种。
取值之一:invoicebalance
orders[].total_usdmoney
订单收取的金额。
orders[].invoice_idstring
订单背后的账单 —— 无论用哪种方式付款,每个订单都有一张。
orders[].itemsint
订单创建或续期多少个权益。
orders[].created_atunix
下单时间。
orders[].delivered_atunix
交付完成的时间。在那之前缺失。
orders[].breakdownobject
客户确认过的那份报价,原样保留 —— 与 Quote 返回的形态相同。
next_cursorcursor
把它作为 cursor 传回以获取下一页。缺失/为空 = 已经取完。
响应示例{
"orders": [
{"order_id": "ord_7b2c9d", "product": "vpn", "kind": "new", "status": "delivered",
"funding": "balance", "total_usd": "11.90", "invoice_id": "inv_5k8p2q",
"items": 1, "created_at": "1785230043", "delivered_at": "1785230103"}
]
}
管理 VPN
https://apiservice.vitamindata.net/api/v1/ListVPN你持有的每个 VPN 账号,附带剩余流量和到期时间。
请求
limitint可选
页大小。默认 50,最大 200。
cursorcursor可选
上一次响应的 next_cursor。第一页时省略。
请求示例curl https://apiservice.vitamindata.net/api/v1/ListVPN \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"limit":25,"cursor":""}'
响应200 · application/json
vpns[].vpn_idstring
其他所有 VPN 动词都使用的公开 id。
vpns[].usernamestring
应用中显示的凭据名称。
vpns[].statusstring
面板所显示的账号状态 —— 除非被暂停或已过期,否则为 active。
vpns[].remaining_bytesbytes
其所有流量包合计的剩余流量。
vpns[].total_downloadbytes
历史下载量,由实时 VPN 平面报告。在 ListVPN 中始终为 0——列表来自缓存读模型,其中没有分方向数据。列表请用 used_bytes,分方向请用 GetVPN/GetVPNUsage。
vpns[].total_uploadbytes
历史上传量。与 total_download 同样的注意事项:在 ListVPN 中为 0。
vpns[].used_bytesbytes
实际消耗的历史总流量(下载 + 上传)。该数值对每个 VPN 都会维护,因此在包括 ListVPN 在内的所有端点上都是正确的。
vpns[].expires_atunix
账号的到期时间。
vpns[].max_onlineint
允许的并发设备数。
vpns[].daily_limit_bytesbytes
今日上限。缺失/0 = 没有每日上限。
vpns[].daily_used_bytesbytes
今日上限中已消耗的量。
vpns[].daily_reset_unixunix
每日计数器的重置时间。
vpns[].allowed_protocolsint
供我们的应用使用的协议位掩码。视为不透明值。
vpns[].cache_atunix
数字有多新鲜:除非设置了 live,它们就和这个时间戳一样旧。
vpns[].created_atunix
账号的创建时间。
vpns[].livebool
这些数字是刚刚从网络取回的,而不是来自缓存。
next_cursorcursor
把它作为 cursor 传回以获取下一页。缺失/为空 = 已经取完。
响应示例{
"vpns": [{
"vpn_id": "vpn_6t2k9p",
"username": "u482913",
"status": "active",
"remaining_bytes": "96636764160",
"total_download": "10737418240",
"used_bytes": "11811160064",
"total_upload": "1073741824",
"expires_at": "1793188800",
"max_online": 3,
"cache_at": "1785412700",
"created_at": "1785000000"
}],
"next_cursor": "vpn_6t2k9p"
}
https://apiservice.vitamindata.net/api/v1/GetVPN单个账号的明细。live:true 表示这些数字是刚刚从网络取回的。
请求
vpn_idstring必填
账号的公开 id(vpn_…),来自 ListVPN 或订单的交付结果。
请求示例curl https://apiservice.vitamindata.net/api/v1/GetVPN \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"vpn_id":"vpn_6t2k9p"}'
响应200 · application/json
vpn.vpn_idstring
其他所有 VPN 动词都使用的公开 id。
vpn.usernamestring
应用中显示的凭据名称。
vpn.statusstring
面板所显示的账号状态 —— 除非被暂停或已过期,否则为 active。
vpn.remaining_bytesbytes
其所有流量包合计的剩余流量。
vpn.total_downloadbytes
历史下载量,由实时 VPN 平面报告。在 ListVPN 中始终为 0——列表来自缓存读模型,其中没有分方向数据。列表请用 used_bytes,分方向请用 GetVPN/GetVPNUsage。
vpn.total_uploadbytes
历史上传量。与 total_download 同样的注意事项:在 ListVPN 中为 0。
vpn.used_bytesbytes
实际消耗的历史总流量(下载 + 上传)。该数值对每个 VPN 都会维护,因此在包括 ListVPN 在内的所有端点上都是正确的。
vpn.expires_atunix
账号的到期时间。
vpn.max_onlineint
允许的并发设备数。
vpn.daily_limit_bytesbytes
今日上限。缺失/0 = 没有每日上限。
vpn.daily_used_bytesbytes
今日上限中已消耗的量。
vpn.daily_reset_unixunix
每日计数器的重置时间。
vpn.allowed_protocolsint
供我们的应用使用的协议位掩码。视为不透明值。
vpn.cache_atunix
数字有多新鲜:除非设置了 live,它们就和这个时间戳一样旧。
vpn.created_atunix
账号的创建时间。
vpn.livebool
这些数字是刚刚从网络取回的,而不是来自缓存。
livebool
刚从网络取回。缺失 = 来自读取模型,数据和 cache_at 一样旧。
响应示例{
"vpn": {
"vpn_id": "vpn_6t2k9p",
"username": "u482913",
"status": "active",
"remaining_bytes": "96636764160",
"total_download": "10737418240",
"used_bytes": "11811160064",
"total_upload": "1073741824",
"expires_at": "1793188800",
"max_online": 3,
"cache_at": "1785412700",
"created_at": "1785000000"
},
"live": true
}
https://apiservice.vitamindata.net/api/v1/GetVPNUsage已用与剩余流量,以及今日上限(如果有)。
请求
vpn_idstring必填
账号的公开 id(vpn_…),来自 ListVPN 或订单的交付结果。
请求示例curl https://apiservice.vitamindata.net/api/v1/GetVPNUsage \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"vpn_id":"vpn_6t2k9p"}'
响应200 · application/json
remaining_bytesbytes
剩余流量。
total_downloadbytes
累计下载量。
daily_limit_bytesbytes
今日上限。缺失 = 没有。
daily_used_bytesbytes
今日上限中已消耗的量。
daily_reset_unixunix
每日计数器的重置时间。
seriesarray
为历史用量序列预留 —— 目前为空。
series[].rxbytes
该时间桶内的下载量。
series[].txbytes
该时间桶内的上传量。
响应示例{
"vpn_id": "vpn_6t2k9p",
"remaining_bytes": "96636764160",
"total_download": "10737418240",
"total_upload": "1073741824",
"expires_at": "1793188800",
"daily_limit_bytes": "53687091200",
"daily_used_bytes": "1273741824",
"daily_reset_unix": "1785456000",
"cache_at": "1785412700",
"live": true
}
https://apiservice.vitamindata.net/api/v1/ListVPNBundles一个账号背后的流量钱包,按它们将被消耗的顺序排列。
这就是你回答“为什么我的客户还有免费流量,付费流量却在减少?”的方式 —— 接下来消耗的是 queue_position 1。live:false 表示我们读不到它们,这与“没有”不是一回事。
请求
vpn_idstring必填
账号的公开 id(vpn_…),来自 ListVPN 或订单的交付结果。
请求示例curl https://apiservice.vitamindata.net/api/v1/ListVPNBundles \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"vpn_id":"vpn_6t2k9p"}'
响应200 · application/json
bundlesarray
钱包列表,按消耗顺序排列。
bundles[].bundle_idstring
该钱包的 id。
bundles[].freebool
由免费额度授予,而非购买所得。
bundles[].sourceenum
钱包的来源。
取值之一:buyextendmigratedfree_tier
bundles[].granted_bytesbytes
授予时的完整容量。
bundles[].remaining_bytesbytes
其中剩余的量。
bundles[].granted_atunix
授予时间。
bundles[].expires_atunix
无论是否用完,它都在此时失效。
bundles[].daily_limit_bytesbytes
它自己的每日上限。缺失 = 没有。
bundles[].statusenum
用单词而非数字表示,这样你永远不用去记 2 代表已用尽。
取值之一:activedisabledexhausted
bundles[].queue_positionint
在可用钱包中按消耗顺序从 1 起编号 —— 1 是下一个被消耗的。0/缺失表示它已不在队列中(用尽、过期或被停用)。
bundles[].plan_gbint
售出时标称的大小,以 GB 计。
bundles[].plan_daysint
售出时标称的有效期,以天计。
bundles[].invoice_idstring
它来自哪笔购买。免费授予时缺失。
livebool
缺失/false = 权益平面无法访问,因此列表是空的而不是错的。“我们读不到”和“确实没有”是两句不同的话。
响应示例{
"bundles": [
{"bundle_id": "bnd_2m8x", "source": "buy",
"granted_bytes": "107374182400", "remaining_bytes": "96636764160",
"granted_at": "1785000000", "expires_at": "1793188800",
"status": "active", "queue_position": 1, "plan_gb": 100, "plan_days": 30,
"invoice_id": "inv_5k8p2q"},
{"bundle_id": "bnd_9k1f", "free": true, "source": "free_tier",
"granted_bytes": "5368709120", "remaining_bytes": "5368709120",
"granted_at": "1784000000", "expires_at": "1793188800",
"status": "active", "queue_position": 2, "plan_gb": 5, "plan_days": 30}
],
"live": true
}
POST
GetSubscriptionLink
read
https://apiservice.vitamindata.net/api/v1/GetSubscriptionLink客户应用要导入的订阅链接。这就是一笔 VPN 销售的交付物。
请求
vpn_idstring必填
账号的公开 id(vpn_…),来自 ListVPN 或订单的交付结果。
请求示例curl https://apiservice.vitamindata.net/api/v1/GetSubscriptionLink \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"vpn_id":"vpn_6t2k9p"}'
响应200 · application/json
subscription_urlstring
把它交给客户的应用 —— 这就是全部交付物。
tokenstring
裸 token,用于自行构建二维码或应用导入链接。
响应示例{
"subscription_url": "https://sub.example.com/s/9f3kq8x2",
"token": "9f3kq8x2"
}
POST
SetVPNPassword
credentials
https://apiservice.vitamindata.net/api/v1/SetVPNPassword修改账号的密码。
需要单独的 credentials 权限 —— manage 从不隐含它。
请求
vpn_idstring必填
账号的公开 id(vpn_…),来自 ListVPN 或订单的交付结果。
new_passwordstring必填
要设置的密码。
credentialstring可选
指定哪个凭据,用于多凭据账号。留空 = 主凭据。
请求示例curl https://apiservice.vitamindata.net/api/v1/SetVPNPassword \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"vpn_id":"vpn_6t2k9p","new_password":"s3cr3t-Enough","credential":""}'
响应200 · application/json
usernamestring
本次修改实际作用到的凭据。
响应示例{"username": "u482913"}
https://apiservice.vitamindata.net/api/v1/SetVPNState暂停或恢复一个账号。
请求
vpn_idstring必填
账号的公开 id(vpn_…),来自 ListVPN 或订单的交付结果。
stateenum必填
要执行的动作。
取值之一:suspendresume
请求示例curl https://apiservice.vitamindata.net/api/v1/SetVPNState \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"vpn_id":"vpn_6t2k9p","state":"suspend"}'
响应200 · application/json
statusenum
账号最终所处的状态。
取值之一:suspendedactive
响应示例{"status": "suspended"}
https://apiservice.vitamindata.net/api/v1/DeleteVPN删除一个账号。不可撤销,也不退款。
请求
vpn_idstring必填
账号的公开 id(vpn_…),来自 ListVPN 或订单的交付结果。
请求示例curl https://apiservice.vitamindata.net/api/v1/DeleteVPN \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"vpn_id":"vpn_6t2k9p"}'
响应200 · application/json
statusenum
成功时恒为 deleted。
取值之一:deleted
响应示例{"status": "deleted"}
销售服务器
VPS 的销售与 VPN 的销售是同一套付款契约 —— 只有购物车不同。
https://apiservice.vitamindata.net/api/v1/GetVPSStorefront位置、每个位置上定价的套餐,以及可引导的镜像。
available:false 的节点已无容量 —— 可以展示,但不要售卖。
请求
请求示例curl https://apiservice.vitamindata.net/api/v1/GetVPSStorefront \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{}'
响应200 · application/json
nodesarray
位置列表,每个位置都有自己定价的套餐。
nodes[].node_idstring
购物车 node_id 所需的值。
nodes[].labelstring
显示名称(Frankfurt)。
nodes[].regionstring
用于分组的粗粒度区域代码。
nodes[].countrystring
ISO 国家代码,用于显示国旗。
nodes[].availablebool
缺失/false = 容量已满:可以展示,但不要售卖。
nodes[].plansarray
此处可售的内容,已附价格。
nodes[].plans[].plan_codestring
购物车 plan_code 所需的值。
nodes[].plans[].namestring
显示名称。
nodes[].plans[].vcpuint
核心数。
nodes[].plans[].ram_mbint
内存,以 MB 计。
nodes[].plans[].disk_gbint
磁盘,以 GB 计。
nodes[].plans[].traffic_bytesbytes
包含的每月流量。
nodes[].plans[].price_usd_monthmoney
该节点上的月度价格 —— 同一套餐在其他节点可能价格不同。
images[].shastring
镜像唯一的标识符 —— 购物车、重装和挂载 ISO 都用它。
images[].namestring
人类可读的名称(Debian 13)。
images[].kindenum
disk 镜像直接开通;iso 是需要从中引导的安装器。
取值之一:diskiso
images[].os_familyenum
供你的 UI 分组和显示图标之用。
取值之一:linuxwindowsmikrotik
images[].min_disk_gbint
往比这更小的磁盘上重装会被拒绝 —— 请先扩大磁盘。
months_minint
购买新 VM 的最短期限。
响应示例{
"nodes": [
{"node_id": "de1", "label": "Frankfurt", "region": "eu", "country": "DE", "available": true,
"plans": [
{"plan_code": "s2", "name": "S2", "vcpu": 2, "ram_mb": 4096, "disk_gb": 40,
"traffic_bytes": "2199023255552", "price_usd_month": "8.00"}
]}
],
"images": [
{"sha": "9a1b8c2d7e6f", "name": "Debian 13", "kind": "disk", "os_family": "linux", "min_disk_gb": 10}
],
"months_min": 1,
"months_max": 12
}
https://apiservice.vitamindata.net/api/v1/ListVPSImages你可以引导或安装的每个镜像,按 sha 标识。
购物车、重装和挂载 ISO 都接受这个 sha。除此之外没有任何东西能标识一个镜像。
请求
请求示例curl https://apiservice.vitamindata.net/api/v1/ListVPSImages \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{}'
响应200 · application/json
images[].shastring
镜像唯一的标识符 —— 购物车、重装和挂载 ISO 都用它。
images[].namestring
人类可读的名称(Debian 13)。
images[].kindenum
disk 镜像直接开通;iso 是需要从中引导的安装器。
取值之一:diskiso
images[].os_familyenum
供你的 UI 分组和显示图标之用。
取值之一:linuxwindowsmikrotik
images[].min_disk_gbint
往比这更小的磁盘上重装会被拒绝 —— 请先扩大磁盘。
响应示例{
"images": [
{"sha": "9a1b8c2d7e6f", "name": "Debian 13", "kind": "disk", "os_family": "linux", "min_disk_gb": 10},
{"sha": "3f4e5d6c7b8a", "name": "Windows Server 2025 installer", "kind": "iso",
"os_family": "windows", "min_disk_gb": 40}
]
}
https://apiservice.vitamindata.net/api/v1/QuoteVPS一台新服务器的价格,逐项列出。
请求
cart.node_idstring必填
在哪里创建 VM,取自店面的节点。
cart.placementstring保留字段 —— 请勿发送
保留字段。在这套 API 上,服务器创建在哪里始终由 node_id 决定 —— 请发送它,并自行从店面挑选节点。
取值之一:auto
cart.plan_codestring必填
套餐,取自所选节点自己的价格表 —— 套餐和价格因节点而异。
cart.image_shastring必填
要引导或安装的镜像,按 sha 指定。磁盘镜像直接开通;安装 ISO 会被挂载,且 VM 被设为从它引导。
cart.namestring必填
VM 的主机名/标签。
cart.monthsint必填
初始期限,须在店面的月数边界内。
cart.extra_disk_gbint可选
在套餐之外追加的磁盘,以 GB 计。
cart.extra_ipsint可选
额外的公网 IPv4 地址。
cart.extra_traffic_tbmoney可选
额外的每月流量,以 TB 计,十进制字符串("0.5")。
请求示例curl https://apiservice.vitamindata.net/api/v1/QuoteVPS \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"cart":{"node_id":"de1","plan_code":"s2","image_sha":"9a1b8c2d7e6f","months":2,"name":"web-1","extra_disk_gb":20,"extra_ips":1,"extra_traffic_tb":"0.5"}}'
响应200 · application/json
quoteobject
逐项列出的价格。不会创建任何东西,也不会收费。
quote.model_namestring
由哪个定价模型作答。
quote.model_typestring
该模型的引擎版本。
quote.base_usdmoney
折扣与附加费之前的价格。
quote.total_usdmoney
最终价格 —— 用这个购物车下单就收这么多。
quote.linesarray
逐项明细,带符号,加总恰好等于总额。
quote.lines[].codestring
这一行是什么(base、某个折扣码、某项附加费……)。
quote.lines[].kindstring
该行的类别,供你的 UI 分组。
quote.lines[].amount_usdmoney
带符号。折扣为负;各行加总恰好等于 total_usd。
quote.lines[].pctstring
该行背后的百分比(如果有)。
quote.cappedbool
总额触到了定价模型的上限。
quote.floor_appliedbool
总额被抬高到定价模型的下限。
quote.clampedenum
当购物车的某个取值在定价前被限制回边界内时设置。
取值之一:minmax
quote.invalidstring
非空表示该购物车无法定价 —— 把它展示出来,且绝不要按这样的报价收费。
quote.metamap
模型附加信息,string→string(例如升级的 remaining_days)。
响应示例{
"quote": {
"model_name": "vps_plan",
"model_type": "vps_plan_v1",
"base_usd": "16.00",
"total_usd": "16.00",
"lines": [
{"code": "plan_s2", "kind": "base", "amount_usd": "16.00"}
],
"meta": {"months": "2"}
}
}
POST
CreateVPSOrder
buyIdempotency-Key
https://apiservice.vitamindata.net/api/v1/CreateVPSOrder购买并开通一台服务器。
用 GetOrder 轮询交付,然后用 GetVPS 查看机器。
请求
cartobject必填
要创建什么 —— 与 QuoteVPS 定价的形态相同。
cart.node_idstring必填
在哪里创建 VM,取自店面的节点。
cart.placementstring保留字段 —— 请勿发送
保留字段。在这套 API 上,服务器创建在哪里始终由 node_id 决定 —— 请发送它,并自行从店面挑选节点。
取值之一:auto
cart.plan_codestring必填
套餐,取自所选节点自己的价格表 —— 套餐和价格因节点而异。
cart.image_shastring必填
要引导或安装的镜像,按 sha 指定。磁盘镜像直接开通;安装 ISO 会被挂载,且 VM 被设为从它引导。
cart.namestring必填
VM 的主机名/标签。
cart.monthsint必填
初始期限,须在店面的月数边界内。
cart.extra_disk_gbint可选
在套餐之外追加的磁盘,以 GB 计。
cart.extra_ipsint可选
额外的公网 IPv4 地址。
cart.extra_traffic_tbmoney可选
额外的每月流量,以 TB 计,十进制字符串("0.5")。
fundingenum必填
如何付款 —— 参见付款方式。没有默认值:省略会被拒绝。
取值之一:FUNDING_AUTOFUNDING_BALANCEFUNDING_INVOICE
expected_total_usdmoney可选
确认保护。设置后,如果我们最新的报价与之不同,这笔销售会以 price_changed 被拒绝,而不是按客户从未见过的金额收费。
请求示例curl https://apiservice.vitamindata.net/api/v1/CreateVPSOrder \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"cart":{"node_id":"de1","plan_code":"s2","image_sha":"9a1b8c2d7e6f","months":2,"name":"web-1","extra_disk_gb":20,"extra_ips":1,"extra_traffic_tb":"0.5"},"funding":"FUNDING_AUTO","expected_total_usd":"36.00"}'
响应200 · application/json
orderobject
订单 —— 轮询 GetOrder 直到状态变为 delivered。
order.order_idstring
订单的公开 id(ord_…)。
order.productenum
买的是什么。
取值之一:vpnvps
order.kindstring
购买的形式:new、extend、upgrade……
order.statusenum
生命周期。delivered 是目标;needs_operator 表示钱已到账、有人正在人工完成交付 —— 不要重新购买;expired 表示账单在未支付的情况下已过期。
取值之一:createdinvoicedpaiddeliveringdeliveredneeds_operatorfailedrefund_pendingrefundedexpired
order.fundingenum
实际使用了哪种付款方式。FUNDING_AUTO 最终会落到其中一种。
取值之一:invoicebalance
order.total_usdmoney
订单收取的金额。
order.invoice_idstring
订单背后的账单 —— 无论用哪种方式付款,每个订单都有一张。
order.itemsint
订单创建或续期多少个权益。
order.created_atunix
下单时间。
order.delivered_atunix
交付完成的时间。在那之前缺失。
order.breakdownobject
客户确认过的那份报价,原样保留 —— 与 Quote 返回的形态相同。
invoiceobject
订单背后的账单:payment_required 时可支付,completed 时已结清。
invoice.invoice_idstring
网关的账单 id(inv_…)。
invoice.statusenum
pending 表示可支付。从 confirmed 到 delivered_redirected 的所有状态都表示钱已不可逆地到账 —— 把它们全部当作已支付。expired 表示链接在未支付的情况下已失效。
取值之一:pendingconfirmedsweepingsweptdeliveringdelivereddelivered_redirectedexpired
invoice.pay_urlstring
托管的支付页面。把客户引导到这里;所有支付通道(币种、链、余额)都在它后面。
invoice.pay_telegram_urlstring
同一张账单,可在 Telegram 内支付:它会打开支付服务商自己的机器人,由机器人显示金额并在那里收款。把它放在 pay_url 旁边,供不愿离开应用的客户使用。可能缺失 —— 只有配置了机器人的支付服务商才有,所以绝不要把它当作你唯一的支付按钮。
invoice.price_usdmoney
账单收取的金额。
invoice.expires_atunix
支付窗口的关闭时间。
paidbool
钱已收讫。状态为 payment_required 时缺失(= false)。
statusenum
就靠这个字段来分支 —— 参见付款方式。
取值之一:completedpayment_required
响应示例{
"order": {
"order_id": "ord_2f8k3j", "product": "vps", "kind": "new",
"status": "invoiced", "funding": "invoice", "total_usd": "16.00",
"invoice_id": "inv_7h4w9s", "items": 1, "created_at": "1785412800"
},
"invoice": {
"invoice_id": "inv_7h4w9s", "status": "pending",
"pay_url": "https://pay.example.com/i/inv_7h4w9s",
"price_usd": "16.00", "expires_at": "1785499200"
},
"status": "payment_required"
}
https://apiservice.vitamindata.net/api/v1/QuoteVPSExtend续费一台服务器要多少钱。
请求
vps_idstring必填
服务器的 id,来自 ListVPS。
monthsint必填
要增加多少个月。店面的 months_min…months_max 是你的 UI 应当提供的范围,但续费并不会把它限制回这个区间 —— 请发送一个合理的数字,因为你发多少,就按多少定价和收费。
请求示例curl https://apiservice.vitamindata.net/api/v1/QuoteVPSExtend \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"vps_id":"vm_7q3k1n","months":1}'
响应200 · application/json
quoteobject
逐项列出的价格。不会创建任何东西,也不会收费。
quote.model_namestring
由哪个定价模型作答。
quote.model_typestring
该模型的引擎版本。
quote.base_usdmoney
折扣与附加费之前的价格。
quote.total_usdmoney
最终价格 —— 用这个购物车下单就收这么多。
quote.linesarray
逐项明细,带符号,加总恰好等于总额。
quote.lines[].codestring
这一行是什么(base、某个折扣码、某项附加费……)。
quote.lines[].kindstring
该行的类别,供你的 UI 分组。
quote.lines[].amount_usdmoney
带符号。折扣为负;各行加总恰好等于 total_usd。
quote.lines[].pctstring
该行背后的百分比(如果有)。
quote.cappedbool
总额触到了定价模型的上限。
quote.floor_appliedbool
总额被抬高到定价模型的下限。
quote.clampedenum
当购物车的某个取值在定价前被限制回边界内时设置。
取值之一:minmax
quote.invalidstring
非空表示该购物车无法定价 —— 把它展示出来,且绝不要按这样的报价收费。
quote.metamap
模型附加信息,string→string(例如升级的 remaining_days)。
响应示例{
"quote": {
"model_name": "vps_plan",
"model_type": "vps_plan_v1",
"base_usd": "16.00",
"total_usd": "16.00",
"lines": [
{"code": "plan_s2", "kind": "base", "amount_usd": "16.00"}
],
"meta": {"months": "2"}
}
}
POST
ExtendVPS
buyIdempotency-Key
https://apiservice.vitamindata.net/api/v1/ExtendVPS为一台服务器续费。
提前续费不会多花钱:新的到期时间从当前到期时间起算,而不是从今天起算。
请求
vps_idstring必填
服务器的 id,来自 ListVPS。
monthsint必填
要增加多少个月。店面的 months_min…months_max 是你的 UI 应当提供的范围,但续费并不会把它限制回这个区间 —— 请发送一个合理的数字,因为你发多少,就按多少定价和收费。
fundingenum必填
如何付款 —— 参见付款方式。没有默认值:省略会被拒绝。
取值之一:FUNDING_AUTOFUNDING_BALANCEFUNDING_INVOICE
expected_total_usdmoney可选
确认保护。设置后,如果我们最新的报价与之不同,这笔销售会以 price_changed 被拒绝,而不是按客户从未见过的金额收费。
请求示例curl https://apiservice.vitamindata.net/api/v1/ExtendVPS \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"vps_id":"vm_7q3k1n","months":1,"funding":"FUNDING_AUTO","expected_total_usd":"8.00"}'
响应200 · application/json
orderobject
订单 —— 轮询 GetOrder 直到状态变为 delivered。
order.order_idstring
订单的公开 id(ord_…)。
order.productenum
买的是什么。
取值之一:vpnvps
order.kindstring
购买的形式:new、extend、upgrade……
order.statusenum
生命周期。delivered 是目标;needs_operator 表示钱已到账、有人正在人工完成交付 —— 不要重新购买;expired 表示账单在未支付的情况下已过期。
取值之一:createdinvoicedpaiddeliveringdeliveredneeds_operatorfailedrefund_pendingrefundedexpired
order.fundingenum
实际使用了哪种付款方式。FUNDING_AUTO 最终会落到其中一种。
取值之一:invoicebalance
order.total_usdmoney
订单收取的金额。
order.invoice_idstring
订单背后的账单 —— 无论用哪种方式付款,每个订单都有一张。
order.itemsint
订单创建或续期多少个权益。
order.created_atunix
下单时间。
order.delivered_atunix
交付完成的时间。在那之前缺失。
order.breakdownobject
客户确认过的那份报价,原样保留 —— 与 Quote 返回的形态相同。
invoiceobject
订单背后的账单:payment_required 时可支付,completed 时已结清。
invoice.invoice_idstring
网关的账单 id(inv_…)。
invoice.statusenum
pending 表示可支付。从 confirmed 到 delivered_redirected 的所有状态都表示钱已不可逆地到账 —— 把它们全部当作已支付。expired 表示链接在未支付的情况下已失效。
取值之一:pendingconfirmedsweepingsweptdeliveringdelivereddelivered_redirectedexpired
invoice.pay_urlstring
托管的支付页面。把客户引导到这里;所有支付通道(币种、链、余额)都在它后面。
invoice.pay_telegram_urlstring
同一张账单,可在 Telegram 内支付:它会打开支付服务商自己的机器人,由机器人显示金额并在那里收款。把它放在 pay_url 旁边,供不愿离开应用的客户使用。可能缺失 —— 只有配置了机器人的支付服务商才有,所以绝不要把它当作你唯一的支付按钮。
invoice.price_usdmoney
账单收取的金额。
invoice.expires_atunix
支付窗口的关闭时间。
paidbool
钱已收讫。状态为 payment_required 时缺失(= false)。
statusenum
就靠这个字段来分支 —— 参见付款方式。
取值之一:completedpayment_required
响应示例{
"order": {
"order_id": "ord_5d1p8m", "product": "vps", "kind": "extend",
"status": "paid", "funding": "balance", "total_usd": "8.00",
"invoice_id": "inv_1c6v3z", "items": 1, "created_at": "1785412800"
},
"invoice": {
"invoice_id": "inv_1c6v3z", "status": "confirmed", "price_usd": "8.00"
},
"paid": true,
"status": "completed"
}
https://apiservice.vitamindata.net/api/v1/QuoteVPSUpgrade更大的配置要多少钱,按已经付过费的时间按比例计算。
请求
vps_idstring必填
服务器的 id,来自 ListVPS。
specobject必填
目标配置。省略/为零的字段保持当前值。
spec.vcpuint可选
目标核心数。0 保持当前值。
spec.ram_mbint可选
目标内存,以 MB 计。0 保持当前值。
spec.disk_gbint可选
目标磁盘大小,以 GB 计。磁盘只能变大 —— 更小的值会被拒绝,因为在运行中的操作系统之下收缩文件系统等于丢数据。
请求示例curl https://apiservice.vitamindata.net/api/v1/QuoteVPSUpgrade \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"vps_id":"vm_7q3k1n","spec":{"vcpu":4,"ram_mb":8192,"disk_gb":80}}'
响应200 · application/json
quoteobject
逐项列出的价格。不会创建任何东西,也不会收费。
quote.model_namestring
由哪个定价模型作答。
quote.model_typestring
该模型的引擎版本。
quote.base_usdmoney
折扣与附加费之前的价格。
quote.total_usdmoney
最终价格 —— 用这个购物车下单就收这么多。
quote.linesarray
逐项明细,带符号,加总恰好等于总额。
quote.lines[].codestring
这一行是什么(base、某个折扣码、某项附加费……)。
quote.lines[].kindstring
该行的类别,供你的 UI 分组。
quote.lines[].amount_usdmoney
带符号。折扣为负;各行加总恰好等于 total_usd。
quote.lines[].pctstring
该行背后的百分比(如果有)。
quote.cappedbool
总额触到了定价模型的上限。
quote.floor_appliedbool
总额被抬高到定价模型的下限。
quote.clampedenum
当购物车的某个取值在定价前被限制回边界内时设置。
取值之一:minmax
quote.invalidstring
非空表示该购物车无法定价 —— 把它展示出来,且绝不要按这样的报价收费。
quote.metamap
模型附加信息,string→string(例如升级的 remaining_days)。
restart_requiredbool
应用这个配置需要重启机器 —— 客户应当在付款之前就知道这一点。
monthly_before_usdmoney
当前的周期性价格。
monthly_after_usdmoney
升级后的周期性价格 —— 今后续费就按这个数收。
响应示例{
"quote": {
"model_name": "vps_upgrade",
"model_type": "vps_plan_v1",
"base_usd": "4.20",
"total_usd": "4.20",
"lines": [
{"code": "prorate_vcpu", "kind": "vps_upgrade", "amount_usd": "2.40"},
{"code": "prorate_ram", "kind": "vps_upgrade", "amount_usd": "1.80"}
],
"meta": {"remaining_days": "21", "monthly_delta_usd": "6.00", "quote_expires_at": "1785416400"}
},
"restart_required": true,
"monthly_before_usd": "8.00",
"monthly_after_usd": "14.00"
}
POST
UpgradeVPS
buyIdempotency-Key
https://apiservice.vitamindata.net/api/v1/UpgradeVPS为更大的配置付款并应用它。磁盘只能变大。
请求
vps_idstring必填
服务器的 id,来自 ListVPS。
specobject必填
目标配置 —— 请先报价;报价也会告诉你是否需要重启。
spec.vcpuint可选
目标核心数。0 保持当前值。
spec.ram_mbint可选
目标内存,以 MB 计。0 保持当前值。
spec.disk_gbint可选
目标磁盘大小,以 GB 计。磁盘只能变大 —— 更小的值会被拒绝,因为在运行中的操作系统之下收缩文件系统等于丢数据。
fundingenum必填
如何付款 —— 参见付款方式。没有默认值:省略会被拒绝。
取值之一:FUNDING_AUTOFUNDING_BALANCEFUNDING_INVOICE
expected_total_usdmoney可选
确认保护。设置后,如果我们最新的报价与之不同,这笔销售会以 price_changed 被拒绝,而不是按客户从未见过的金额收费。
请求示例curl https://apiservice.vitamindata.net/api/v1/UpgradeVPS \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"vps_id":"vm_7q3k1n","spec":{"vcpu":4,"ram_mb":8192,"disk_gb":80},"funding":"FUNDING_AUTO","expected_total_usd":"4.20"}'
响应200 · application/json
orderobject
订单 —— 轮询 GetOrder 直到状态变为 delivered。
order.order_idstring
订单的公开 id(ord_…)。
order.productenum
买的是什么。
取值之一:vpnvps
order.kindstring
购买的形式:new、extend、upgrade……
order.statusenum
生命周期。delivered 是目标;needs_operator 表示钱已到账、有人正在人工完成交付 —— 不要重新购买;expired 表示账单在未支付的情况下已过期。
取值之一:createdinvoicedpaiddeliveringdeliveredneeds_operatorfailedrefund_pendingrefundedexpired
order.fundingenum
实际使用了哪种付款方式。FUNDING_AUTO 最终会落到其中一种。
取值之一:invoicebalance
order.total_usdmoney
订单收取的金额。
order.invoice_idstring
订单背后的账单 —— 无论用哪种方式付款,每个订单都有一张。
order.itemsint
订单创建或续期多少个权益。
order.created_atunix
下单时间。
order.delivered_atunix
交付完成的时间。在那之前缺失。
order.breakdownobject
客户确认过的那份报价,原样保留 —— 与 Quote 返回的形态相同。
invoiceobject
订单背后的账单:payment_required 时可支付,completed 时已结清。
invoice.invoice_idstring
网关的账单 id(inv_…)。
invoice.statusenum
pending 表示可支付。从 confirmed 到 delivered_redirected 的所有状态都表示钱已不可逆地到账 —— 把它们全部当作已支付。expired 表示链接在未支付的情况下已失效。
取值之一:pendingconfirmedsweepingsweptdeliveringdelivereddelivered_redirectedexpired
invoice.pay_urlstring
托管的支付页面。把客户引导到这里;所有支付通道(币种、链、余额)都在它后面。
invoice.pay_telegram_urlstring
同一张账单,可在 Telegram 内支付:它会打开支付服务商自己的机器人,由机器人显示金额并在那里收款。把它放在 pay_url 旁边,供不愿离开应用的客户使用。可能缺失 —— 只有配置了机器人的支付服务商才有,所以绝不要把它当作你唯一的支付按钮。
invoice.price_usdmoney
账单收取的金额。
invoice.expires_atunix
支付窗口的关闭时间。
paidbool
钱已收讫。状态为 payment_required 时缺失(= false)。
statusenum
就靠这个字段来分支 —— 参见付款方式。
取值之一:completedpayment_required
响应示例{
"order": {
"order_id": "ord_5d1p8m", "product": "vps", "kind": "extend",
"status": "paid", "funding": "balance", "total_usd": "8.00",
"invoice_id": "inv_1c6v3z", "items": 1, "created_at": "1785412800"
},
"invoice": {
"invoice_id": "inv_1c6v3z", "status": "confirmed", "price_usd": "8.00"
},
"paid": true,
"status": "completed"
}
管理服务器
这里的每个动词都通过 id 指定服务器 —— 在这些调用上字段就叫 id,与花钱动词所用的 vps_id 不同。
https://apiservice.vitamindata.net/api/v1/ListVPS你的机器,附带电源状态和地址。
请求
cursorcursor可选
上一次响应的 next_cursor。第一页时省略。
请求示例curl https://apiservice.vitamindata.net/api/v1/ListVPS \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"limit":50,"cursor":""}'
响应200 · application/json
vps[].idstring
服务器的 id —— 所有管理动词的 id 和所有花钱动词的 vps_id 都用它。
vps[].namestring
它的主机名/标签。
vps[].node_idstring
它运行在哪个节点。
vps[].lifecycleenum
0 开通中 · 1 活跃 · 2 已暂停 · 3 删除中 · 4 已删除。
取值之一:01234
vps[].provisionedbool
机器已在宿主机上存在。
vps[].power_desiredenum
电源的期望状态:1 开机,0/缺失为关机。实时状态看 GetVPSStats.running。
取值之一:01
vps[].mem_mbint
内存,以 MB 计。
vps[].disk_gbint
磁盘,以 GB 计。
vps[].image_shastring
它从哪个镜像引导或安装。
vps[].expires_atunix
服务器的到期时间 —— 请在此之前用 ExtendVPS 续费。
vps[].created_atunix
创建时间。
vps[].private_ipstring
它的内网地址(当套餐包含时)。
next_cursorcursor
把它作为 cursor 传回以获取下一页。缺失/为空 = 已经取完。
响应示例{
"vps": [{
"id": "vm_7q3k1n",
"name": "web-1",
"node_id": "de1",
"lifecycle": 1,
"provisioned": true,
"power_desired": 1,
"vcpu": 2,
"mem_mb": 4096,
"disk_gb": 40,
"image_sha": "9a1b8c2d7e6f",
"expires_at": "1793188800",
"created_at": "1785000000",
"ips": ["203.0.113.10"],
"private_ip": "10.77.0.10"
}]
}
https://apiservice.vitamindata.net/api/v1/GetVPS单台机器的明细。
请求
idstring必填
服务器的 id,来自 ListVPS。注意管理动词上的字段名是 id —— 只有花钱的动词写作 vps_id。
请求示例curl https://apiservice.vitamindata.net/api/v1/GetVPS \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"id":"vm_7q3k1n"}'
响应200 · application/json
vps.idstring
服务器的 id —— 所有管理动词的 id 和所有花钱动词的 vps_id 都用它。
vps.node_idstring
它运行在哪个节点。
vps.lifecycleenum
0 开通中 · 1 活跃 · 2 已暂停 · 3 删除中 · 4 已删除。
取值之一:01234
vps.provisionedbool
机器已在宿主机上存在。
vps.power_desiredenum
电源的期望状态:1 开机,0/缺失为关机。实时状态看 GetVPSStats.running。
取值之一:01
vps.image_shastring
它从哪个镜像引导或安装。
vps.expires_atunix
服务器的到期时间 —— 请在此之前用 ExtendVPS 续费。
vps.private_ipstring
它的内网地址(当套餐包含时)。
响应示例{
"vps": {
"id": "vm_7q3k1n",
"name": "web-1",
"node_id": "de1",
"lifecycle": 1,
"provisioned": true,
"power_desired": 1,
"vcpu": 2,
"mem_mb": 4096,
"disk_gb": 40,
"image_sha": "9a1b8c2d7e6f",
"expires_at": "1793188800",
"created_at": "1785000000",
"ips": ["203.0.113.10"],
"private_ip": "10.77.0.10"
},
"live": true
}
https://apiservice.vitamindata.net/api/v1/GetVPSStats实时的 CPU、内存、磁盘和网络。
请求
idstring必填
服务器的 id,来自 ListVPS。注意管理动词上的字段名是 id —— 只有花钱的动词写作 vps_id。
请求示例curl https://apiservice.vitamindata.net/api/v1/GetVPSStats \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"id":"vm_7q3k1n"}'
响应200 · application/json
响应示例{
"cpu_pct": 12,
"mem_used_mb": 1536,
"disk_used_mb": 9216,
"rx_bps": "1048576",
"tx_bps": "524288",
"running": true,
"updated_at": "1785412790"
}
https://apiservice.vitamindata.net/api/v1/GetVPSUsage按流量包统计的、已从机器额度中消耗的流量。
请求
idstring必填
服务器的 id,来自 ListVPS。注意管理动词上的字段名是 id —— 只有花钱的动词写作 vps_id。
请求示例curl https://apiservice.vitamindata.net/api/v1/GetVPSUsage \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"id":"vm_7q3k1n"}'
响应200 · application/json
bundlesarray
流量包列表,current 标记当前正在消耗的那个。
bundles[].idint64
流量包在计算平面上的 id。
bundles[].modeint
该平面的计费模式代码。视为不透明值。
bundles[].bytes_totalbytes
流量包的总额度。
bundles[].used_dlbytes
已从中消耗的下载量。
bundles[].used_upbytes
已从中消耗的上传量。
bundles[].stateint
该平面的状态代码。视为不透明值。
bundles[].currentbool
这是当前正在消耗的流量包。
bundles[].expires_atunix
流量包的失效时间。
响应示例{
"total_down": "53687091200",
"total_up": "10737418240",
"bundles": [
{"id": "41", "mode": 1, "bytes_total": "2199023255552",
"used_dl": "53687091200", "used_up": "10737418240",
"state": 1, "current": true, "expires_at": "1793188800"}
]
}
https://apiservice.vitamindata.net/api/v1/VPSPower电源控制。
shutdown 是请求操作系统关机;force_stop 是直接断电。优先用前者。
请求
idstring必填
服务器的 id,来自 ListVPS。注意管理动词上的字段名是 id —— 只有花钱的动词写作 vps_id。
actionenum必填
shutdown/reboot 是平滑操作;reset/force_stop 相当于直接按电源键。
取值之一:startshutdownrebootresetforce_stop
请求示例curl https://apiservice.vitamindata.net/api/v1/VPSPower \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"id":"vm_7q3k1n","action":"reboot"}'
响应200 · application/json
okbool
底层平面已接受该操作。用 GetVPSStats 观察机器的实际状态。
https://apiservice.vitamindata.net/api/v1/ReinstallVPS清空磁盘并安装一个全新的镜像。
破坏性操作,且重试并不安全 —— 一次调用,一次重装。镜像必须能装进当前磁盘;装不下就先把磁盘扩大。
请求
idstring必填
服务器的 id,来自 ListVPS。注意管理动词上的字段名是 id —— 只有花钱的动词写作 vps_id。
image_shastring必填
镜像,用 ListVPSImages 里的 sha 指定。除此之外没有别的方式标识镜像,不在目录中的 sha 会被拒绝。
reset_rootbool可选
同时生成一个新的 root 密码。
请求示例curl https://apiservice.vitamindata.net/api/v1/ReinstallVPS \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"id":"vm_7q3k1n","image_sha":"9a1b8c2d7e6f","reset_root":true}'
响应200 · application/json
okbool
底层平面已接受该操作。用 GetVPSStats 观察机器的实际状态。
https://apiservice.vitamindata.net/api/v1/AttachVPSISO挂载一个安装 ISO。要从它引导,请把引导顺序设为 1。
请求
idstring必填
服务器的 id,来自 ListVPS。注意管理动词上的字段名是 id —— 只有花钱的动词写作 vps_id。
image_shastring必填
镜像,用 ListVPSImages 里的 sha 指定。除此之外没有别的方式标识镜像,不在目录中的 sha 会被拒绝。
请求示例curl https://apiservice.vitamindata.net/api/v1/AttachVPSISO \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"id":"vm_7q3k1n","image_sha":"3f4e5d6c7b8a"}'
响应200 · application/json
okbool
底层平面已接受该操作。用 GetVPSStats 观察机器的实际状态。
https://apiservice.vitamindata.net/api/v1/DetachVPSISO卸载 ISO,回到从磁盘引导。
请求
idstring必填
服务器的 id,来自 ListVPS。注意管理动词上的字段名是 id —— 只有花钱的动词写作 vps_id。
请求示例curl https://apiservice.vitamindata.net/api/v1/DetachVPSISO \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"id":"vm_7q3k1n"}'
响应200 · application/json
okbool
底层平面已接受该操作。用 GetVPSStats 观察机器的实际状态。
POST
SetVPSBootOrder
manage
https://apiservice.vitamindata.net/api/v1/SetVPSBootOrder决定哪个设备先引导。
请求
idstring必填
服务器的 id,来自 ListVPS。注意管理动词上的字段名是 id —— 只有花钱的动词写作 vps_id。
orderenum必填
0 磁盘优先,1 CD-ROM 优先。
取值之一:01
请求示例curl https://apiservice.vitamindata.net/api/v1/SetVPSBootOrder \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"id":"vm_7q3k1n","order":1}'
响应200 · application/json
okbool
底层平面已接受该操作。用 GetVPSStats 观察机器的实际状态。