POST /apiv2/time/add
将 TRON 地址添加到 Host Mode,并可选择注册用于接收委托通知的回调 URL。
端点 URL
POST https://netts.io/apiv2/time/add身份验证
在请求体(api_key)或 X-API-KEY 请求头中提供您的 API 密钥。请求 IP 必须在为您 API 密钥配置的白名单中。
请求体
{
"api_key": "your_api_key",
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"callback_url": "https://your-server.com/webhook",
"infinity": true
}参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| api_key | string | 是* | API 密钥。也可以在 X-API-KEY 请求头中发送。 |
| address | string | 是 | TRON(TRC-20)地址,必须匹配 ^T[1-9A-HJ-NP-Za-km-z]{33}$(以 T 开头,34 个字符)。 |
| callback_url | string | 否 | 当向该地址委托 Energy 时用于接收通知的公开 HTTP/HTTPS URL。最多 2048 个字符。 |
| infinity | boolean | 否 | true —— 同时将地址直接切换至 infinity 模式,免去单独调用 /apiv2/time/infinitystart。默认为 false。 |
* 除非使用了 X-API-KEY 请求头,否则请求体中必填。
**callback_url 验证:**必须为 http/https,仅限公开主机(localhost、私有 RFC1918 范围、链路本地 169.254.0.0/16、IPv6 私有/链路本地、保留及多播地址均会被拒绝),且长度最多为 2048 个字符。
行为
- 如果该地址为新地址,它将被添加到 Host Mode 中,状态为未激活(
status = 0,cycle_set = 0)。之后可通过/apiv2/time/order或/apiv2/time/infinitystart将其激活。 - 如果该地址已存在于您的账户下,该调用将更新其回调 URL。
- 如果提供了
callback_url,系统会为该地址存储(或更新)该 URL。
infinity
传入 "infinity": true 时,地址将通过单次调用被添加并激活至 infinity 模式 —— 其效果与先调用 /apiv2/time/add 再调用 /apiv2/time/infinitystart 相同。计费方式与单独调用完全一致:此时不会收取任何费用,随着 Energy 的委托,周期将逐个计费。参见 Host Mode → 周期与定价。
添加地址与开启该模式是两个独立的步骤,且仅第一步是有保证的。 响应仅报告添加的结果。如果地址已添加但未能开启该模式,该调用仍会返回 code: 0 及常规消息 —— 地址仅保持未激活状态,与您未传递该标志时的结果完全相同。在以下情况下将跳过开启操作:
- 您的余额不足以支付当前价格下的一个周期;
- 地址已处于激活状态;
- 地址已存在未完结的订单。
无论是否携带该标志,响应内容均相同 —— 没有额外的字段,没有额外的错误码,并且它不会告知您 infinity 模式是否已实际开启。请通过 Time Status 进行确认:地址将报告 status: "active" 和 mode: "infinity",且订单 ID 包含在该响应中。请勿将此端点返回的 code: 0 视为该模式正在运行的凭证。
请求示例
cURL
curl -X POST https://netts.io/apiv2/time/add \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY_HERE",
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"callback_url": "https://your-server.com/webhook"
}'Python
import requests
url = "https://netts.io/apiv2/time/add"
data = {
"api_key": "YOUR_API_KEY_HERE",
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"callback_url": "https://your-server.com/webhook", # 可选
# "infinity": True, # 可选:同时将地址切换至 infinity 模式
}
resp = requests.post(url, json=data, timeout=30)
result = resp.json()
if result["code"] == 0:
print("Added:", result["data"]["address"])
else:
print("Error:", result["msg"])Node.js
const axios = require('axios');
const data = {
api_key: 'YOUR_API_KEY_HERE',
address: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
// callback_url: 'https://your-server.com/webhook', // 可选
// infinity: true, // 可选:同时将地址切换至 infinity 模式
};
axios.post('https://netts.io/apiv2/time/add', data)
.then(({ data: result }) => {
if (result.code === 0) console.log('Added:', result.data.address);
else console.error('Error:', result.msg);
})
.catch(err => console.error('Request failed:', err.response?.data || err.message));响应
成功(新地址)
{
"code": 0,
"msg": "Address added to Host Mode successfully",
"data": {
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"callback_url": "https://your-server.com/webhook",
"timestamp": "2026-07-13T05:30:15.123456"
}
}成功(更新已有地址的回调 URL)
{
"code": 0,
"msg": "Address callback URL updated successfully",
"data": {
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"callback_url": "https://new-webhook.com/endpoint",
"timestamp": "2026-07-13T05:35:20.789012"
}
}响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| code | integer | 0 = 成功,负数 = 错误 |
| msg | string | 人类可读的消息 |
| data.address | string | 已添加/更新的地址 |
| data.callback_url | string | null | 已注册的回调 URL(若无则为 null) |
| data.timestamp | string | 操作的 ISO 时间戳 |
错误响应
所有错误均使用 code = -1 并在 msg 中描述问题:
| msg | 原因 |
|---|---|
API key required in X-API-KEY header or request body | 未提供 API 密钥 |
Invalid API key or IP not in whitelist | 身份验证失败 |
Invalid TRC-20 address format | 地址不符合要求的格式 |
Invalid callback URL. Only public HTTP/HTTPS URLs are allowed | 回调 URL 未通过验证 |
Address belongs to another user | 该地址已在另一个账户下注册 |
Database error adding/updating address | 临时服务器端错误 —— 请重试 |
Internal server error | 意外错误 —— 请重试或联系支持人员 |
{ "code": -1, "msg": "Invalid API key or IP not in whitelist", "data": null }HTTP 状态码
端点错误以 HTTP 200 和负数 code 返回 —— 请检查 code,而非 HTTP 状态。错误响应体始终包含 "data": null。
部分错误会在请求到达端点之前返回。它们使用非 200 状态以及不同的响应体结构:
| HTTP | 响应体 | 原因 |
|---|---|---|
| 402 | {"detail": {"code": 1004, "msg": "Insufficient funds. Minimum balance is 4 TRX. Please top up your account."}} | 账户余额过低 |
| 403 | {"detail": {"code": 1005, "msg": "API key is blocked. Contact support."}} | API 密钥已被冻结 —— 请联系支持人员 |
| 422 | {"detail": [ … ]} | 请求体未通过验证:缺少必填字段或字段类型错误。请注意此响应中没有 code 字段 |
回调(webhooks)
如果您注册了 callback_url,每当向该地址委托 Energy 时(即在处理委托周期时,每个周期一次),系统都会调用该 URL。
请求格式
系统发送带有查询参数的 HTTP GET 请求:
因 USDT 转账产生的周期 —— 包含 energy_used:
GET https://your-server.com/webhook?address=TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE&order_id=T149936&hash=97b4eb0257088aefcb286229aa42ec750f27554390dd4e186f55efe273666577&balance_after=142.3500&idle_cycle=0&energy_used=65k&charged=2.0000无前置转账的周期 —— 省略 energy_used:
GET https://your-server.com/webhook?address=TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE&order_id=T149937&hash=97b4eb0257088aefcb286229aa42ec750f27554390dd4e186f55efe273666577&balance_after=138.3500&idle_cycle=0&charged=4.0000| 参数 | 说明 |
|---|---|
| address | 接收 Energy 委托的 TRON 地址 |
| order_id | 委托标识符(T + 内部委托 ID)—— 每次委托唯一 |
| hash | Energy 委托的链上交易哈希 |
| balance_after | 本次扣费后您的 TRX 账户余额(扣费时刻的快照;在回调到达时该值可能已发生变化) |
| idle_cycle | 1 —— 此委托是在无转账超过 24 小时后下发的(空闲重新委托),0 —— 由您的转账或激活产生的常规周期 |
| energy_used | 产生该周期的转账所消耗 Energy 的资费档位:65k(65,000 Energy 或更低 → 2 TRX)或 131k(超过 65,000 → 4 TRX)。可选 —— 当没有可测量的前置转账时,该键会从查询字符串中完全省略(而非发送空值):激活时的首次委托、每次空闲重新委托以及尚无消耗历史记录的地址。所有这些均按 4 TRX 的费率计费 |
| charged | 本周期扣除的 TRX 金额 —— 2.0000 或 4.0000,与 energy_used 中的资费档位对应。始终存在,包括省略 energy_used 的情况。参见 Host Mode → 周期与定价 |
使用 order_id 和 hash 来区分不同的委托并与您自己的记录进行对账 —— 同一地址的两次回调会因这些值而有所不同。使用 charged 来跟踪每个周期的支出而无需轮询 /apiv2/time/status,使用 energy_used 查看上一次转账属于哪个资费档位。请将 energy_used 作为可选参数读取 —— 缺少该键意味着“没有可测量的转账”,而不是错误,并且绝不要为其假设默认值。
处理器示例(Python / Flask)
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhook', methods=['GET'])
def energy_delegation_webhook():
address = request.args.get('address')
order_id = request.args.get('order_id')
tx_hash = request.args.get('hash')
charged = request.args.get('charged') # 本周期扣除的 TRX
energy_used = request.args.get('energy_used') # '65k' | '131k' | None(该键可能不存在)
if not address:
return jsonify({"error": "Missing address parameter"}), 400
# 您的业务逻辑(基于 order_id / hash 实现幂等)
print(f"Energy delegated: address={address} order_id={order_id} hash={tx_hash} "
f"charged={charged} energy_used={energy_used}")
return jsonify({"status": "success"}), 200交付行为
- 方法: GET,超时时间约 10 秒。返回 HTTP 200 以确认收到。
- 重试: 如果请求失败,最多尝试 3 次;如果全部失败,回调将被丢弃(无论如何,Energy 委托仍会正常执行)。
- 无签名: 请求未经 NETTS 签名。密钥(若有)为您自行嵌入到
callback_url中的任何内容。 - 对账: 由于回调可能会丢失,因此也请轮询
/apiv2/time/status并使您的处理器具备幂等性。
更新 / 移除回调
- 更新: 再次调用
/apiv2/time/add,传入相同的地址和新的callback_url。 - 移除: 调用
/apiv2/time/delete移除该地址(这也会同时移除其回调);如需重新添加,可以在不带callback_url的情况下再次添加。
相关端点
- POST /apiv2/time/order — 购买周期(激活地址)
- POST /apiv2/time/infinitystart — 启用 infinity 模式
- POST /apiv2/time/status — 检查状态与周期
- POST /apiv2/time/stop — 停止 Host Mode
- POST /apiv2/time/delete — 移除地址
注意事项
- 新地址初始状态为未激活;可通过订单、infinity 启动或在此处传递
"infinity": true来将其激活。 - 同一地址不能在两个不同的账户下注册。
- 在添加地址之前,应先在 TRON 网络上将其激活。