错误与约定
本页说明 TRONAgg API 如何报告失败,以及每个端点都遵循的通用规则:错误信封、完整的错误代码目录、购买的幂等性、分页方式,以及你在每个响应中都会遇到的单位与格式。
错误信封
错误使用标准 HTTP 状态码,外加一个带顶层 detail 的 JSON 响应体。大多数端点在 detail 中放一个结构化对象:机器可读的 error 代码、人类可读的 message,以及——少数错误才有的——额外上下文字段。
{
"detail": {
"error": "insufficient_balance",
"current_balance": 1200000,
"required_amount": 3500000
}
}
请根据 detail.error 分支处理;存在 detail.message 时,可将其展示给用户。
如实列出的例外
少数响应不遵循带 error 的对象结构。请做防御性处理——读取 detail,并注意:
-
纯字符串
detail。 某些响应的detail是一个裸字符串而不是对象。它们是:- 任意 API 密钥端点上的
401——"API key required"、"Invalid API key"或"User not found"。 - 任意 API 密钥端点上账户被封禁时的
403——"Account is blocked"。(另一种403,即ip_not_allowed,是对象。) - 任意 API 密钥端点上的
429——"Rate limit exceeded",并带Retry-After响应头。见速率限制。 POST /webhooks/{id}/test上的429——"Too many webhook tests; limit is 5 per hour"。上限为每个账户每小时 5 次测试,与工作台中的测试按钮共用。GET /order/{id}上的404——"Order not found"(订单存在但不属于你时也返回它)。- 公开能量估算接口返回的所有错误(
/calculator/estimate-energy、/calculator/estimate-energy/usdt/…)——例如422"Invalid TRON address format: …"、429"Rate limit exceeded"。只有缺少必填参数时才返回下文所述的422数组。 - 意外错误时的
500——"Internal server error",出现在任何自身没有结构化internal_error的端点上。
{ "detail": "Order not found" } - 任意 API 密钥端点上的
-
以
code而非error为键的对象。POST /buy上的订单数量限制错误使用code(外加min/max)——见订单数量限制。 -
请求校验
422。 格式错误的请求体或超出范围的查询参数(例如resource_amount≤ 0,或page_size大于 100)会被框架以422拒绝,detail为字段错误数组。detail为对象的422只有下文列出的业务错误(AutoEnergy 的invalid_address以及 Energy Agent 的各个代码)。{ "detail": [ { "loc": ["query", "resource_amount"], "msg": "...", "type": "..." } ] }
因此,健壮的客户端应检查 detail 的类型:对象 → 根据 detail.error 分支处理(没有时回退到 detail.code);字符串 → 视为给人看的消息;数组 → 请求校验错误。
错误代码
编程式 API
error 代码 | HTTP | 端点 | 额外字段 | 触发时机 |
|---|---|---|---|---|
ip_not_allowed | 403 | 所有使用 API 密钥认证的端点 | message | 来源 IP 不在该密钥的可选白名单内,或无法确定来源 IP。请在 工作台 → API 密钥 → IP 访问权限 中更新白名单,或清空白名单以取消限制。 |
invalid_address | 400 | POST /buy | message | receiver_address 不是有效的 TRON 地址。在任何扣款之前校验。 |
unsupported_resource | 400 | GET /estimate、POST /buy | message | 传入了 ENERGY 或 BANDWIDTH 以外的 resource_type,或(POST /buy)只能购买能量的账户下了带宽订单。 |
invalid_duration | 400 | GET /estimate | message | 传入了 1h 以外的 duration。(POST /buy 会将其作为 422 请求体校验错误拒绝。) |
invalid_idempotency_key | 400 | POST /buy | message | Idempotency-Key 超过 128 个字符。 |
insufficient_balance | 400 | POST /buy | current_balance、required_amount | 余额低于订单总额(两者单位均为 SUN)。此端点上没有 message 字段。 |
validation_error | 400 | POST /webhooks | message | Webhook URL 被拒:不是 HTTPS;主机不是公网主机(私有、回环或链路本地地址,无法解析,或是 tronagg.ai 主机);该 URL 已连接;或账户已有 10 个 Webhook。 |
webhook_deposit_required | 400 | POST /webhooks | message、total_deposited_sun、required_total_deposited_sun | 使用 Webhook 需要净确认充值超过 1 TRX:已确认的充值减去提现(含提现手续费)。购买不会减少该数值。total_deposited_sun 是你当前的净值;required_total_deposited_sun 是门槛(1000001)。 |
invalid_cursor | 400 | GET /transactions | message | cursor 值无法解析。 |
reseller_suspended | 403 | POST /buy | — | 你的账户已被暂停购买。请联系客服。 |
not_found | 404 | DELETE /webhooks/{id}、POST /webhooks/{id}/test | message | 你的账户下没有该 id 的 Webhook。 |
duplicate_request | 409 | POST /buy | message | 具有相同 Idempotency-Key 的请求仍在处理中。见幂等性。 |
delivery_failed | 502 | POST /webhooks/{id}/test | message | 测试投递未成功。 |
service_unavailable | 503 | GET /estimate、POST /buy | message | 能量购买暂时不可用。 |
reseller_activation_balance_low | 503 | POST /buy | — | 你的账户暂时无法购买。请稍后重试。 |
internal_error | 500 | POST /buy | message | 意外的服务端错误(已记录以便排查)。订单未创建;请稍后重试。 |
关于 POST /buy 上的 order_amount_below_minimum / order_amount_above_maximum 代码,见订单数量限制。
AutoEnergy
AutoEnergy 端点(/autoenergy/*)使用对象信封——{"error": <code>, "message": <text>}——代码如下:
error 代码 | HTTP | 触发时机 |
|---|---|---|
insufficient_balance | 400 | 订阅或重新激活:你的余额低于准入门槛——激活费 + 一次每日费 + 一笔 131k 档转账。(与 POST /buy 不同,此处带 message。) |
reseller_suspended | 403 | 你的账户已被暂停使用 AutoEnergy。请联系客服。 |
not_found | 404 | 此账户下没有该订阅。 |
address_busy | 409 | 该地址已有一个生效中的订阅——可能是你的,也可能是其他账户的。如果 GET /autoenergy/subscriptions/{address} 能返回它,则无需任何操作;若那里返回 404,说明该地址由其他账户覆盖。在你的订阅关闭后,若另一个订阅占用了该地址,重新激活也会返回此代码。 |
address_exists | 409 | 你在该地址上有一个已关闭的订阅。请先重新激活或删除它。 |
not_reactivatable | 409 | 只有已关闭的订阅才能重新激活。 |
not_deletable | 409 | 只有已关闭的订阅才能删除。请先关闭它。 |
invalid_address | 422 | 该地址不是有效的 TRON 地址。 |
fulfiller_unavailable | 502 | 无法启动或恢复能量委托;请重试。 |
autoenergy_temporarily_unavailable | 503 | 你的账户暂时无法使用 AutoEnergy;请稍后重试。 |
reseller_activation_balance_low | 503 | 你的账户暂时无法使用 AutoEnergy;请稍后重试。 |
internal_error | 500 | 意外的服务端错误(已记录以便排查)。请稍后重试。 |
这些端点返回的其他 422——例如 expire_at 早于当前时间,或 idle_hours 超出 24–72——属于请求校验错误,detail 为数组,而不是上述对象。
Energy Agent
Energy Agent 端点(/agent/*,以及公开的 GET /pay/{public_id})返回业务错误时,代码位于 detail.error,有时带额外上下文字段,并且没有 message——请自行将代码映射为提示文案。认证错误与请求校验的 422 数组遵循上文的通用规则。
{ "detail": { "error": "below_min_balance", "min_balance_sun": 10000000, "balance_sun": 2500000 } }
error 代码 | HTTP | 端点 | 额外字段 | 触发时机 |
|---|---|---|---|---|
program_disabled | 403 | POST /agent/configs、POST /agent/configs/{id}/resume | — | 该计划目前不接受新建或恢复配置。 |
not_found | 404 | PATCH / DELETE /agent/configs/{id}、POST /agent/configs/{id}/pause、POST /agent/configs/{id}/resume、GET /pay/{public_id} | — | 你的账户下没有该配置(或没有该付款页面)。 |
address_taken | 409 | POST /agent/configs | — | 该地址已属于一个运行中的配置。 |
admin_paused | 409 | POST /agent/configs/{id}/resume、DELETE /agent/configs/{id} | — | 已被 TRONAgg 客服暂停。请联系客服。 |
generated_not_deletable | 409 | DELETE /agent/configs/{id} | — | TRONAgg 专属地址无法删除;请改为暂停。 |
address_invalid | 422 | POST /agent/configs | — | 不是有效的 TRON 地址,或在 mode: "generated" 时传入了 address。 |
address_reserved | 422 | POST /agent/configs | — | 该地址不能用于自有钱包配置。 |
config_limit | 422 | POST /agent/configs | max_configs | 你的配置数量已达上限。 |
generated_limit | 422 | POST /agent/configs | max_generated | 你的 TRONAgg 专属地址数量已达上限。 |
units_out_of_bounds | 422 | POST /agent/configs、PATCH /agent/configs/{id} | max_units_cap | max_units 超出 1..max_units_cap 范围。 |
energy_out_of_bounds | 422 | POST /agent/configs、PATCH /agent/configs/{id} | energy_min、energy_max | 每份能量低于 energy_min,或能量 × 最多份数高于 energy_max(null = 无上限)。 |
base_not_mtrx | 422 | POST /agent/configs、PATCH /agent/configs/{id} | — | 基础付款不是 0.001 TRX 的正整数倍。 |
base_below_cost | 422 | POST /agent/configs、PATCH /agent/configs/{id} | cost_max_sun | 基础付款低于 TRONAgg 一份能量的最高小时价格。 |
below_min_balance | 422 | POST /agent/configs、POST /agent/configs/{id}/resume | min_balance_sun、balance_sun | 你的余额低于激活门槛。 |
service_unavailable | 503 | GET /agent/summary、GET /agent/quote、POST /agent/configs、PATCH /agent/configs/{id}(修改数值字段时) | — | 价格暂时不可用;请稍后重试。 |
速率限制
每个账户每分钟最多可发出 1,000 个请求,由该账户的所有 API 密钥与已登录的工作台会话共用。超出后,API 返回 429,detail 为纯字符串,并带 Retry-After 响应头,其值为距离窗口重置的秒数——等待该时长后重试。下单是幂等的(见下文),因此在 429 之后重试 POST /buy 是安全的。
HTTP/1.1 429 Too Many Requests
Retry-After: 23
{ "detail": "Rate limit exceeded" }
需要更高的额度?请联系客服并说明你预期的请求速率。
幂等性
POST /buy 是唯一会动用资金的写操作,因此它接受 Idempotency-Key 请求头,使重试变得安全:
- 发送任意不超过 128 个字符的唯一字符串(UUID 是不错的选择)。更长的密钥返回
400 invalid_idempotency_key。 - 使用某个密钥的购买一旦创建成功,其
201响应会被缓存 24 小时,之后任何复用该密钥的请求都会原样得到这一响应——因此超时后重试会返回原订单,而不会再下一单。 - 被拒绝的请求(例如
400 insufficient_balance或400 invalid_address)不会创建订单,也不会占用该密钥;修正原因后用同一密钥重试即可。 - 如果在第一个请求仍在处理时到达了重复请求,会返回
409 duplicate_request。等待几秒后用同一密钥重试;第一个请求完成后,你会得到它的缓存响应。 - 如果第一个请求的处理在我们这一侧被中断(罕见),该密钥可能一直处于"处理中"状态,在长达 24 小时内持续返回
409 duplicate_request。在用新密钥重试之前,请先查看GET /orders(按receiver_address过滤),确认订单是否已创建——新密钥总会创建一笔新订单。 - 密钥按账户隔离,且不与请求体绑定。为一笔确实不同的购买复用同一密钥,会返回第一次购买的响应,而不会创建新订单。
该请求头是可选的,但强烈建议所有自动化买家使用。
分页
共有三个列表端点,而且——出于历史原因——每个的分页方式都不同。请分别按各自的规则使用。
| 端点 | 请求参数 | 响应字段 | 方式 |
|---|---|---|---|
GET /orders | page(≥ 1)、page_size(1–100) | orders、total、page、page_size | 按页码分页,带完整的 total 计数。 |
GET /transactions | limit(1–100)、cursor | transactions、has_more、next_cursor | 基于游标。将上一次的 next_cursor 原样作为 cursor 传回以获取下一页;has_more 为 false 时停止。与你的任何条目都不匹配的游标会从最新条目重新开始;无法解析的游标返回 400 invalid_cursor。 |
GET /deposits | limit(1–100)、offset(≥ 0) | deposits、has_more | limit/offset。每页将 offset 增加 limit;has_more 为 false 时停止。 |
三者均按最新在前返回。/transactions 与 /deposits 没有 total——请根据 has_more 决定是否再取下一页。
GET /orders 的过滤参数
receiver_address对订单的接收地址做精确匹配。请传入完整的 34 位地址;部分地址匹配不到任何订单。status不区分大小写:completed与COMPLETED返回相同的订单。
单位与格式
- SUN。
*_sun字段中的金额是以 SUN 计的整数,SUN 是 TRX 的最小单位:1 TRX = 1,000,000 SUN。按每单位能量计的价格是例外:它们可能带小数,因此GET /estimate的unit_price_sun以及公开价格端点的价格字段(price_sun、our_price_sun、market_avg_price_sun)是十进制字符串(例如"27.000000")。 - 十进制金额是字符串。 面向用户的 TRX 金额(
total_price_trx、amount_trx、balance_trx等)序列化为 JSON 字符串而非数字,以保持精确。请用 decimal 类型解析,切勿使用 float。 - 订单状态为大写。 订单的
status是PENDING、PROCESSING、AWAITING_PAYMENT、COMPLETED或FAILED之一。通过 API 下的订单从PENDING变为COMPLETED或FAILED;另外两种状态可能出现在直接从钱包付款的订单上。COMPLETED与FAILED是终态。 - TRON 地址。 地址是以
T开头、长度为 34 个字符的 base58 字符串。 - 时间戳。 时间字段(
created_at、completed_at等)为 UTC 的 ISO-8601 格式。
订单数量限制
每笔订单都有最小和最大资源数量。可从 GET /estimate 读取当前边界,它会在价格之外返回 min_amount 和 max_amount(null 表示该侧无边界)。
POST /buy 执行同样的边界。超出范围的数量返回 400,其结构化 detail——与其他购买错误不同——以 code(而非 error)为键,并带 min / max:
{
"detail": {
"code": "order_amount_below_minimum",
"message": "Order amount 50000 is below the minimum (64000). Increase the amount or contact support.",
"min": 64000,
"max": 1000000
}
}
以上数值仅为示意;实际边界以 GET /estimate 返回的为准。这两个代码是 order_amount_below_minimum 和 order_amount_above_maximum。请先调用 GET /estimate,避免多一次往返。
下一步
- 身份验证——
X-API-Key请求头以及上文的401响应。 - 购买能量——上述大多数错误的来源,即购买端点。
- Webhook 事件——轮询订单状态之外的推送方案。