Orchestrator — 单次调用批量下单
在单个请求中发送最多 100 个地址,让 Netts 为每个地址完成整个执行流程: 在需要时激活地址,在 Bandwidth 不足时进行补充,然后租赁 Energy —— 自动将大额数量拆分为多个分块。
您将立即收到带有跟踪密钥的 202 Accepted 响应,无需在连接上等待。随后可从状态端点读取进度。
为什么使用它
通常为全新地址订购 Energy 需要按正确顺序执行三次单独调用,并在调用之间自行编写重试逻辑。Orchestrator 将其合并为单个请求,并按地址依次运行以下流程:
probe → activation (if the address is not active) → bandwidth (if free < 400) → energy激活或 Bandwidth 环节的失败不会阻止该地址的 Energy 订单,并且单个地址的失败绝不会影响其他地址。
端点基础 URL
https://netts.io/apiv2/orchestrator请求标头
| 标头 | 必填 | 说明 |
|---|---|---|
| Content-Type | 是 | application/json |
| X-API-KEY | 是 | 来自 Netts 控制面板的 API 密钥 |
| X-Real-IP | 是 | 来自您白名单的 IP 地址 |
| X-Idempotency-Key | 是* | 您为此订单指定的密钥,由 A-Z a-z 0-9 . _ : - 组成的 12–128 个字符 |
* 必须提供 X-Idempotency-Key 标头或请求体中的 clientRequestId 字段之一。如果两者均未发送,请求将被拒绝并返回 5010。
该密钥标识整个订单。使用相同密钥重复请求将返回原始结果,而不是创建第二个订单 —— 参见幂等性。
创建订单 — POST /apiv2/orchestrator
请求体
{
"clientRequestId": "my-batch-2026-01-01-001",
"defaults": {
"bandwidth": true,
"bandwidthAmount": 400,
"bandwidthPeriod": "1h",
"check": true,
"trx_send": false
},
"items": [
{ "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE", "amount": 65000 },
{ "receiveAddress": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "amount": 131000 },
{ "receiveAddress": "TYYyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", "amount": 61000, "bandwidth": false }
]
}顶级字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
items | array | 是 | 1 到 100 个地址。同一订单内的重复地址将被拒绝。 |
clientRequestId | string | 否 | 您的订单参考编号,由 A-Z a-z 0-9 . _ : - 组成的 8–128 个字符。若标头缺失,可兼作幂等性密钥。 |
defaults | object | 否 | 应用于所有未覆盖这些值的项的默认值。 |
子项字段
除 receiveAddress 和 amount 之外的所有字段均可在 defaults 中设置。单项中设置的值优先于默认值。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
receiveAddress | string | — | 接收 Energy 的 TRON 地址 |
amount | int | — | 该地址所需的 Energy,61 000 … 50 000 000 |
bandwidth | bool | true | 当该地址不足时为其订购 Bandwidth |
bandwidthAmount | int | 400 | 400 或 5000 |
bandwidthPeriod | string | 1h | 5m 或 1h |
check | bool | 见下文 | 首先检查可用 Bandwidth,若充足则跳过订购 |
trx_send | bool | false | 透传给 Bandwidth 服务 |
activation | bool | true | 如果地址未激活则将其激活。对于您明确已知已激活的地址,可设为 false 以跳过该步骤。 |
当 bandwidthAmount 为 400 时,check 默认为 true,否则默认为 false —— 订购 5 000 个单位通常意味着无论当前已有多少,您都需要它们。
数量按单个地址计算。 单个请求可以自由混合不同的数量;唯一的上限是总量。
限制
| 限制项 | 限值 |
|---|---|
| 每个订单的地址数 | 100 |
| 每个地址的 Energy | 61 000 … 50 000 000 |
| 每个订单的 Energy 总量 | 50 000 000 |
| 每个账户进行中的订单数 | 3 |
| 每个账户进行中的地址数 | 300 |
| 订单被受理所需的最低余额 | 4 TRX |
50 000 000 的上限适用于请求中所有地址的总和,而非单个地址。
响应 — 已受理 (202, 状态码 10202)
{
"detail": {
"code": 10202,
"status": "accepted",
"msg": "Order accepted for processing",
"data": {
"idempotencyKey": "my-batch-2026-01-01-001",
"requestId": 1234,
"itemsAccepted": 3,
"statusUrl": "/apiv2/orchestrator/status/my-batch-2026-01-01-001",
"items": [
{
"deliveryKey": 5001,
"trackingId": "my-batch-2026-01-01-001:TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"amount": 65000,
"energyChunks": 1,
"activation": "planned",
"bandwidth": "planned",
"status": "queued"
}
]
}
}
}202 意味着已排队,尚未执行。目前尚未扣除任何费用。请轮询 statusUrl 获取结果。
trackingId 是幂等性密钥 + 地址对 —— 即订单内单个地址的唯一标识。请在您自己的日志记录和对账中使用它。
示例
curl -X POST https://netts.io/apiv2/orchestrator \
-H "Content-Type: application/json" \
-H "X-API-KEY: your_api_key" \
-H "X-Real-IP: your_whitelisted_ip" \
-H "X-Idempotency-Key: my-batch-2026-01-01-001" \
-d '{
"items": [
{"receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE", "amount": 65000}
]
}'查询进度 — GET /apiv2/orchestrator/status/{idempotencyKey}
添加 ?address=T… 可仅获取单个地址而非整个订单的信息。
{
"detail": {
"code": 10000,
"status": "processing",
"data": {
"idempotencyKey": "my-batch-2026-01-01-001",
"requestId": 1234,
"clientRequestId": "my-batch-2026-01-01-001",
"summary": {
"total": 3, "queued": 1, "processing": 1, "completed": 1,
"partial": 0, "failed": 0, "insufficient_balance": 0,
"credentials_revoked": 0, "cancelled": 0
},
"items": [
{
"deliveryKey": 5001,
"trackingId": "my-batch-2026-01-01-001:TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"status": "completed",
"energy": {
"requested": 65000,
"delegated": 65000,
"status": "done",
"chunks": { "total": 1, "done": 1 },
"orderIds": ["1Hxxxxxxxxxx"],
"hashes": ["0000000000000000000000000000000000000000000000000000000000000000"]
},
"activation": { "status": "not_needed", "orderId": null, "hash": null },
"bandwidth": {
"status": "enough", "orderId": "B1Hxxxxxxxxxxxxxx",
"amount": 400, "period": "1h", "hashes": [], "skipReason": null
},
"attempts": 1,
"startedAt": "2026-01-01T00:00:00+00:00",
"finishedAt": "2026-01-01T00:00:03+00:00"
}
]
}
}
}未知的密钥,或属于其他账户的密钥,将返回 404。
地址状态值
| 状态 | 含义 |
|---|---|
queued | 等待处理 |
processing | 正在处理 |
completed | 所有请求的 Energy 均已代理 |
partial | 部分分块已交付,部分失败 |
failed | 未交付任何资源 |
insufficient_balance | 已终止 — 您的余额低于最低要求 |
credentials_revoked | 订单运行期间,您的 API 密钥被移除或禁用 |
cancelled | 根据您的取消请求已从队列中移除 |
步骤状态值
| 步骤 | 取值 |
|---|---|
activation | not_needed、done、failed、skipped、skipped_unavailable |
bandwidth | enough、done、failed、skipped |
energy | done、partial、failed |
bandwidth.skipReason 解释了 skipped 的原因:option_off(您禁用了该选项),energy_gt_600000(大额 Energy 订单无需补充 Bandwidth)。
代理哈希
energy.hashes 是您的交付凭证。当 Energy 来自外部提供商时,下单时哈希尚不可知 —— 它会在大约一分钟后填入,在收集到哈希或等待窗口超时之前,该地址不会报告为已完成。处于 completed 状态且存在哈希的地址即表示已完全交割。
取消 — POST /apiv2/orchestrator/cancel/{idempotencyKey}
从队列中移除所有尚未被处理的地址。
{
"detail": {
"code": 10005,
"status": "cancelled",
"msg": "Order cancelled: 7 addresses removed from queue",
"data": { "cancelled": 7 }
}
}已处于 processing 状态的地址不会被中断:其部分 Energy 可能已经完成付款。取消操作仅对剩余部分尽力而为。
幂等性
订单由您的密钥标识 —— 即 X-Idempotency-Key 标头,或标头缺失时的 clientRequestId。
| 重复请求情况 | 结果 |
|---|---|
| 相同密钥,相同请求体 | 208,返回原始订单及 originalAcceptedAt — 不会生成第二个订单 |
| 相同密钥,不同请求体 | 409 4090 IDEMPOTENCY_CONFLICT |
因此,您那边因网络超时而原样重试是安全的。在已使用的密钥下更改有效负载将被拒绝,而不是静默应用。
在订单内部,每个地址都带有自己的内部密钥,因此重复请求也绝不会对单个地址重复扣费。
计费
Orchestrator 本身不收取费用。每个步骤由执行该步骤的服务按其正常价格计费:
| 步骤 | 计费方式 |
|---|---|
| Activation | 独立扣费,订单号为 A… |
| Bandwidth | 独立扣费,订单号为 B1H… — 仅在实际代理时收取 |
| Energy | 每个分块扣费一次,订单号为 1H… |
在可用 Bandwidth 充足时,设置 check: true 不产生任何费用 —— 状态为 enough 且不会下单。大额 Energy 数量会完全跳过 Bandwidth。
如果您的余额在批处理中途耗尽,剩余地址将以 insufficient_balance 结束,且不会再尝试执行。
错误代码参考
| 代码 | 说明 | HTTP 状态码 |
|---|---|---|
10202 | 订单已受理 / 已被受理 | 202 / 208 |
10000 | 状态已返回 | 200 |
10005 | 订单已取消 | 200 |
5004 | 字段无效:地址格式错误、amount 超出范围、bandwidthAmount 不为 400/5000、bandwidthPeriod 不为 5m/1h、请求体不是 JSON 对象 | 400 |
5005 | items 缺失或为空 | 400 |
5006 | 同一订单内存在重复的 receiveAddress | 400 |
5009 | X-Idempotency-Key 或 clientRequestId 格式错误 | 400 |
5010 | 未提供 X-Idempotency-Key 且未提供 clientRequestId | 400 |
5012 | 请求中的 Energy 总量超过 50 000 000 | 400 |
-1 | API 密钥无效 / IP 不在白名单中 | 401 |
1004 | 余额低于 4 TRX 最低要求 | 402 |
-1 | 未找到订单(或不属于您) | 404 |
4090 | IDEMPOTENCY_CONFLICT — 相同密钥,不同请求体 | 409 |
4220 | 请求验证失败(详情见 data.errors) | 422 |
429 / 5011 | 进行中的订单、地址或分块过多 | 429 |
5003 | 订单未被受理 — 服务暂时不可用,可安全重试 | 503 |
创建时的 503 属于故障安全:未存储任何内容,也未扣除任何费用。
速率限制
按源 IP 进行限制:
| 周期 | 限额 |
|---|---|
| 1 秒 | 20 个请求 |
超出速率限制 (429)
{ "message": "API rate limit exceeded" }注意事项
- 202 并非交付回执。 请将其视为“已排队”。最终结果存在于状态端点中。
- 地址并行运行,单个订单内最多同时处理 5 个地址,因此大型批处理不会因单个慢地址而阻塞。不保证完成顺序。
- 自动分块:超过 1 000 000 的数量会被拆分为均匀的分块,每个分块成为独立的 Energy 订单。
energy.orderIds和energy.hashes会列出所有分块。 - Orchestrator 订单整体没有 webhook。 每次 Energy 代理仍会生成常规的
delegation.confirmedwebhook,请参见 Webhooks。 - 相关端点: Activator、Bandwidth、Order 1H。