Orders — API reference
Buying and inspecting rentals. There is no single-order cancel in v1:
POST /v1/orders charges synchronously, so an order is never left sitting unpaid in a
queue and created is barely observable. 3002 order_not_cancellable belongs to
POST /v1/batches/{id}/cancel, where receivers that have already been picked up cannot
be pulled back.
| Method | Path | Summary |
|---|---|---|
GET | /v1/orders | List orders |
POST | /v1/orders | Create an order |
GET | /v1/orders/{orderId} | Order detail |
POST | /v1/orders/{orderId}/reclaim | Return the resource before expiry |
Base URL https://api.tenergy.me/v1, or https://api-nile.tenergy.me/v1 on Nile (Environments). Every request below is signed as in Authentication unless its Auth line says otherwise.
List orders
GET /v1/orders · listOrders
Auth: API key (HMAC).
Newest first. Filters combine with AND.
format=csv answers text/csv with every matching order rather than one page
(limit and cursor are ignored), streamed, with the same fields as the JSON list:
one column per Order field in contract order, activation.* and failure.*
flattened, delegate_hashes space-separated. A text cell that begins with =, +,
-, @, a tab or a carriage return is prefixed with ' so a spreadsheet does not
run it as a formula.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | array of enum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refunded | Repeat the parameter to match several states. | |
resource | query | enum: energy, bandwidth, activation | ||
receiver | query | string | ||
client_order_id | query | string | Exact match. The fastest way to find an order after a lost response. | |
group_id | query | string | Exact match on the order’s group_id — every order of one payout run, customer or batch of yours. | |
label | query | string | Exact match on the order’s label. | |
created_after | query | string (date-time) | ||
created_before | query | string (date-time) | ||
from | query | string (date-time) | Inclusive lower bound on created_at — the dashboard’s date range. | |
to | query | string (date-time) | Exclusive upper bound on created_at. | |
format | query | enum: json, csv | ||
limit | query | integer | ||
cursor | query | string | Opaque cursor from a previous response’s next_cursor. |
Responses
| Status | Meaning |
|---|---|
200 | OK |
400 | Malformed request — bad JSON, unknown field, wrong type. |
401 | Missing, malformed or rejected credentials. |
429 | Too many requests. |
500 | Something broke on our side. |
Response fields
| Field | Type | Required | Description |
|---|---|---|---|
data | array of object (Order) | yes | |
data[].id | string | yes | |
data[].client_order_id | string | null | ||
data[].group_id | string | null | The group_id you sent with the order, or null. | |
data[].label | string | null | The label you sent with the order, or null. | |
data[].release_when_used_pct | integer | null | The early-release threshold you set, or null (held for the full term). | |
data[].whole_only | boolean | The order is filled by one order at one provider, never in parts (whole_only on create or quote). | |
data[].account_id | string | yes | |
data[].batch_id | string | null | Set when the order was produced by a batch. | |
data[].subscription_id | string | null | Set when the order was produced by a subscription refill. | |
data[].resource | enum: energy, bandwidth, activation | yes | energy — TRON energy, the resource a TRC-20 transfer consumes. · bandwidth — TRON bandwidth (net), consumed by transaction size. · activation — one-off account activation; amount and tier do not apply. |
data[].amount | integer | null | What was ordered. | |
data[].delivered_amount | integer | null | What was actually delegated. Equal to amount or slightly above it on a normal order (a delegation from stake is rounded up by a small margin so the receiver never gets less); below it when partial is true. null until delivery. Mirrors BatchItem.delivered_amount. | |
data[].partial | boolean | True when some allocations landed and some did not, so the receiver got delivered_amount instead of amount and the difference was refunded pro rata (see refunded_amount_sun). Partial delivery is a field, not an order state: the order still runs through confirmed → active. A client that ignores this field sees a delivered order, which is why it defaults to false and is always present once the order has been delivered. | |
data[].tier | enum (14 values, Tier) | null | ||
data[].filled_tier | enum (14 values, Tier) | null | The term actually bought. An order is filled by the cheapest provider term not shorter than tier, so this can be longer than tier (a 5-minute order filled with 15 minutes) and never shorter. When parts of an order were bought at different terms, the shortest of them. null until a part is placed, and on orders placed before this field existed (their term is tier). expires_at follows the term bought. | |
data[].duration_seconds | integer | null | The tier expressed in seconds, so a client need not parse the slug. | |
data[].receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
data[].source | enum: api, dashboard, transfer, bot, subscription, batch, proxy, x402, promo, activation | Where the order came from. transfer is a direct-transfer purchase with no account; x402 is a purchase paid with USDC on Base through x402, also with no account; promo is the free grant of the promo token redeem, no payment and no account. activation is an internal rental onto one of our activator contract’s callers, no payment and no account; customers never see one. | |
data[].status | enum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refunded | yes | The one order state machine, spelled identically in this contract, Webhooks and the dashboard: |
data[].confirm_status | enum: unconfirmed, confirmed, confirm_failed | yes | On-chain confirmation of the delegation, independent of the order’s business state. unconfirmed means the transaction has not been seen in a block yet — it is not a failure. |
data[].price_sun_per_unit | integer | null | ||
data[].pay_amount_sun | integer (int64) | Charged for the resource itself. | |
data[].activate_amount_sun | integer (int64) | Charged for activating the receiver; 0 when no activation was needed. | |
data[].total_amount_sun | integer (int64) | yes | pay_amount_sun + activate_amount_sun. What left the balance. |
data[].provider_amount_sun | integer | null | The provider price inside total_amount_sun, before the service fee. null on lines priced without a fee (orders before 2026-10-06, bandwidth, activation, contract prices). | |
data[].fee | object (ServiceFee) | null | ||
data[].fee.bps | integer | yes | Basis points of the provider price: 500 = 5 %. |
data[].fee.amount_sun | integer (int64) | yes | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. |
data[].fee.source | enum: tier, promo | yes | |
data[].refunded_amount_sun | integer (int64) | Credited back so far. Non-zero for failed and refunded orders. | |
data[].delegate_hash | string | null | First delegation transaction. Convenience field — identical to delegate_hashes[0]. null until the delegation is broadcast. | |
data[].delegate_hashes | array of string | All delegation transactions for this order. More than one when the amount was filled from several stake addresses. Always present, possibly empty. | |
data[].delegated_at | string (date-time) | null | ||
data[].reclaim_hash | string | null | ||
data[].reclaimed_at | string (date-time) | null | ||
data[].expires_at | string (date-time) | null | When the rental window ends. null until delegation. | |
data[].activation | object | What happened about activating the receiver. | |
data[].activation.performed | boolean | ||
data[].activation.hash | string | null | ||
data[].activation.amount_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
data[].memo | string | null | ||
data[].created_at | string (date-time) | yes | |
data[].updated_at | string (date-time) | ||
data[].failure | null | object | Present and non-null only for failed orders. | |
data[].failure.code | integer | yes | |
data[].failure.slug | string | yes | |
data[].failure.message | string | yes | |
data[].failure.at | string (date-time) | ||
data[].savings | null | object (OrderSavings) | The savings receipt: what this order cost against burning TRX for the same energy. null until the delegation is confirmed (confirmed, active, expired, reclaimed), for bandwidth and activation orders, and when the chain’s energy fee could not be read. | |
data[].savings.burn_alternative_sun | integer (int64) | yes | delivered_amount × the chain parameter getEnergyFee — the TRX the receiver would have burned for the same energy. The fee is the chain’s current value on API reads and the value at confirmation in the order.confirmed webhook; it changes only by a Super Representative vote. |
data[].savings.paid_sun | integer | yes | total_amount_sun − refunded_amount_sun: what the order cost net of refunds. |
data[].savings.saved_sun | integer | yes | burn_alternative_sun − paid_sun. Negative when the order cost more than burning; never clamped. |
data[].savings.saved_pct | number | yes | saved_sun / burn_alternative_sun × 100, two decimals. Negative together with saved_sun. |
next_cursor | string | null | yes | Pass back as cursor for the next page; null on the last page. |
Create an order
POST /v1/orders · createOrder
Auth: API key (HMAC).
Buys a rental for one receiver and charges the account balance. A tier whose
GET /v1/prices row says available: false (energy 1d while switched off) is refused
with 2003 tier_unavailable before anything is charged.
The response is not a delivery receipt. A 201 means the order was accepted, paid for
and handed to the supply layer; status tells you how far it got by the time the response
was written. The response is written as soon as the order is accepted and charged, so a
new order normally comes back status: "paid" with no delegate_hash yet (allocating
if the supply layer already started). Delivery follows within seconds: poll
GET /v1/orders/{id} (the SDKs’ waitForOrder does) or, better, subscribe to the
order.confirmed webhook. Treat confirmed and active alike: both mean the
resource is on the receiver.
Check partial. An order whose allocations only partly landed comes back
confirmed/active with partial: true, delivered_amount below amount and the
difference already refunded. It is not a separate state and it is not a failure.
Idempotency. Always send client_order_id. A repeat with the same id returns the
original order with HTTP 200 and charges nothing. This is the correct response to a
network timeout: retry verbatim rather than creating a second order.
Price protection. The price is settled twice.
- At this call. With
quote_idyou are charged exactly the quote’stotal_amount_sun, even if the live price has moved since; without one, the live total.max_price_sunis checked against that charge: above it the order is rejected with3006 price_above_limitand nothing is charged. A charge below the ceiling is taken as it is, never raised to it. - At fill. If the provider the price came from no longer sells at it, the router buys from
the next one. The platform does not cover that rise: the difference (the provider’s cost
with the routing fee, above what you were charged) is debited from your balance, only
within
max_price_sun— without one, within the cost of burning TRX for the same resource — and never beyond your available balance or that burn cost. It shows intotal_amount_sun. When no provider fits within it, the order endsfailedand the whole charge is refunded.
So max_price_sun is the most you will pay, not the price you expect. Leave headroom above
the quote: a ceiling equal to the quoted total leaves none, and any move between the quote
and the fill fails the order. Without a figure of your own, use the burn price: amount ×
100 SUN for energy, × 1,000 SUN for bandwidth (the chain’s fees on mainnet today), plus the
activation fee when the receiver is not active. Headroom is debited only if a dearer fill
uses it.
Key spend limits. A key with daily_limit_sun or monthly_limit_sun refuses an order that would take
it past either with 3026 api_key_spend_limit_reached; nothing is charged. A replay of an existing
client_order_id is never refused by a limit.
Agent spend limits. An order placed with an AI agent’s OAuth access token counts against that connected
agent’s daily (UTC day) and monthly (UTC month) limits; one that would take it past either is refused with
3031 spend_limit_reached (HTTP 403, details.resets_at) and nothing is charged.
Activation. If receiver is not activated on chain, the platform activates it and adds
activate_amount_sun to the charge. Set activate: false to refuse that: the order is
then rejected with 3004 receiver_not_activated and nothing is charged.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key making this mutating request safe to retry, 8–128 characters of A-Z a-z 0-9 . _ : -. A repeat with the same key and the same body returns the original result; the same key with a different body is rejected with 3010 idempotency_conflict. Records live for 24 hours. |
Request body
JSON (OrderRequest), required.
| Field | Type | Required | Description |
|---|---|---|---|
client_order_id | string | Your own id for this order, unique per account. Strongly recommended on every create: it makes the call idempotent and lets you fetch the order later without storing ours (GET /v1/orders/cid:<client_order_id>). | |
quote_id | string | A quote from POST /v1/quotes. You are charged exactly its total_amount_sun now; a dearer fill later is still debited within max_price_sun (see price protection above). | |
resource | enum: energy, bandwidth, activation | energy — TRON energy, the resource a TRC-20 transfer consumes. · bandwidth — TRON bandwidth (net), consumed by transaction size. · activation — one-off account activation; amount and tier do not apply. | |
amount | integer | Energy or bandwidth units. Omit for activation. | |
tier | enum (14 values, Tier) | Rental period, shortest first: minutes (5m–30m), hours (1h–12h) and days (1d–30d). Energy is sold for 5m, 10m, 15m, 30m, 1h and 1d; a term not on sale answers 2003 tier_unavailable. An order is filled by the cheapest provider term not shorter than the one asked (a 5m order may be bought as 15m); the order’s filled_tier says which term was bought. Check available on each GET /v1/prices row; a tier that is not available is rejected with 2003 tier_unavailable. | |
receiver | string | Base58Check TRON address (starts with T, 34 characters). | |
activate | boolean | Activate the receiver if it is not active on chain, adding the activation fee to the charge. With false, an inactive receiver causes 3004 receiver_not_activated and nothing is charged. | |
max_price_sun | integer (int64) | The most you will pay for this order in total (resource + activation), not the price you expect. Checked twice: at this call a charge above it is rejected with 3006 price_above_limit; at fill a dearer provider is paid from your balance only up to it, else the order fails and is refunded. Leave headroom above the quote — set equal to the quoted total, any price move fails the order. Without a figure of your own: amount × the burn price (100 SUN per energy unit on mainnet today). | |
memo | string | null | Free-text note stored with the order and echoed back. Not sent on chain. | |
group_id | string | Your own grouping key for reports (a payout run, a customer, a wallet of yours). Not unique; filter GET /v1/orders?group_id= and the CSV export by it. Not sent on chain. | |
label | string | A short free label for reports (e.g. “withdrawals”, “shop-eu”). Not unique; filterable like group_id. | |
release_when_used_pct | integer | Early release: once the receiver has used this share of what was delegated, we take the rest back before the term ends and the order becomes reclaimed (order.reclaimed). Applies to delegations from our own stake; a part bought from a provider runs its term. The price is the full term’s. | |
whole_only | boolean | true: the order is filled by ONE order at ONE provider, so it is never delivered in parts and never closed short. Default false: a large order may be split across providers when that is cheaper, and a part nobody can deliver is refunded at its own price. |
Example request body, from the contract (illustrative values):
{
"client_order_id": "acme-2026-09-11-000418",
"resource": "energy",
"amount": 65000,
"tier": "1h",
"receiver": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"activate": true
}
Responses
| Status | Meaning |
|---|---|
200 | The client_order_id already exists for this account and the request body matches the original. The existing order is returned; nothing was created and nothing was charged. |
201 | Order created and charged. |
400 | Malformed request — bad JSON, unknown field, wrong type. |
401 | Missing, malformed or rejected credentials. |
402 | Not enough balance to cover the order. |
409 | The request contradicts the current state of the object. |
422 | Syntactically valid but semantically impossible. |
429 | Too many requests. |
500 | Something broke on our side. |
503 | Temporarily unable to serve. On order creation this is fail-secure: nothing was stored and nothing was charged, so retrying verbatim with the same client_order_id is safe. |
Response fields (Order)
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
client_order_id | string | null | ||
group_id | string | null | The group_id you sent with the order, or null. | |
label | string | null | The label you sent with the order, or null. | |
release_when_used_pct | integer | null | The early-release threshold you set, or null (held for the full term). | |
whole_only | boolean | The order is filled by one order at one provider, never in parts (whole_only on create or quote). | |
account_id | string | yes | |
batch_id | string | null | Set when the order was produced by a batch. | |
subscription_id | string | null | Set when the order was produced by a subscription refill. | |
resource | enum: energy, bandwidth, activation | yes | energy — TRON energy, the resource a TRC-20 transfer consumes. · bandwidth — TRON bandwidth (net), consumed by transaction size. · activation — one-off account activation; amount and tier do not apply. |
amount | integer | null | What was ordered. | |
delivered_amount | integer | null | What was actually delegated. Equal to amount or slightly above it on a normal order (a delegation from stake is rounded up by a small margin so the receiver never gets less); below it when partial is true. null until delivery. Mirrors BatchItem.delivered_amount. | |
partial | boolean | True when some allocations landed and some did not, so the receiver got delivered_amount instead of amount and the difference was refunded pro rata (see refunded_amount_sun). Partial delivery is a field, not an order state: the order still runs through confirmed → active. A client that ignores this field sees a delivered order, which is why it defaults to false and is always present once the order has been delivered. | |
tier | enum (14 values, Tier) | null | ||
filled_tier | enum (14 values, Tier) | null | The term actually bought. An order is filled by the cheapest provider term not shorter than tier, so this can be longer than tier (a 5-minute order filled with 15 minutes) and never shorter. When parts of an order were bought at different terms, the shortest of them. null until a part is placed, and on orders placed before this field existed (their term is tier). expires_at follows the term bought. | |
duration_seconds | integer | null | The tier expressed in seconds, so a client need not parse the slug. | |
receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
source | enum: api, dashboard, transfer, bot, subscription, batch, proxy, x402, promo, activation | Where the order came from. transfer is a direct-transfer purchase with no account; x402 is a purchase paid with USDC on Base through x402, also with no account; promo is the free grant of the promo token redeem, no payment and no account. activation is an internal rental onto one of our activator contract’s callers, no payment and no account; customers never see one. | |
status | enum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refunded | yes | The one order state machine, spelled identically in this contract, Webhooks and the dashboard: |
confirm_status | enum: unconfirmed, confirmed, confirm_failed | yes | On-chain confirmation of the delegation, independent of the order’s business state. unconfirmed means the transaction has not been seen in a block yet — it is not a failure. |
price_sun_per_unit | integer | null | ||
pay_amount_sun | integer (int64) | Charged for the resource itself. | |
activate_amount_sun | integer (int64) | Charged for activating the receiver; 0 when no activation was needed. | |
total_amount_sun | integer (int64) | yes | pay_amount_sun + activate_amount_sun. What left the balance. |
provider_amount_sun | integer | null | The provider price inside total_amount_sun, before the service fee. null on lines priced without a fee (orders before 2026-10-06, bandwidth, activation, contract prices). | |
fee | object (ServiceFee) | null | ||
fee.bps | integer | yes | Basis points of the provider price: 500 = 5 %. |
fee.amount_sun | integer (int64) | yes | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. |
fee.source | enum: tier, promo | yes | |
refunded_amount_sun | integer (int64) | Credited back so far. Non-zero for failed and refunded orders. | |
delegate_hash | string | null | First delegation transaction. Convenience field — identical to delegate_hashes[0]. null until the delegation is broadcast. | |
delegate_hashes | array of string | All delegation transactions for this order. More than one when the amount was filled from several stake addresses. Always present, possibly empty. | |
delegated_at | string (date-time) | null | ||
reclaim_hash | string | null | ||
reclaimed_at | string (date-time) | null | ||
expires_at | string (date-time) | null | When the rental window ends. null until delegation. | |
activation | object | What happened about activating the receiver. | |
activation.performed | boolean | ||
activation.hash | string | null | ||
activation.amount_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
memo | string | null | ||
created_at | string (date-time) | yes | |
updated_at | string (date-time) | ||
failure | null | object | Present and non-null only for failed orders. | |
failure.code | integer | yes | |
failure.slug | string | yes | |
failure.message | string | yes | |
failure.at | string (date-time) | ||
savings | null | object (OrderSavings) | The savings receipt: what this order cost against burning TRX for the same energy. null until the delegation is confirmed (confirmed, active, expired, reclaimed), for bandwidth and activation orders, and when the chain’s energy fee could not be read. | |
savings.burn_alternative_sun | integer (int64) | yes | delivered_amount × the chain parameter getEnergyFee — the TRX the receiver would have burned for the same energy. The fee is the chain’s current value on API reads and the value at confirmation in the order.confirmed webhook; it changes only by a Super Representative vote. |
savings.paid_sun | integer | yes | total_amount_sun − refunded_amount_sun: what the order cost net of refunds. |
savings.saved_sun | integer | yes | burn_alternative_sun − paid_sun. Negative when the order cost more than burning; never clamped. |
savings.saved_pct | number | yes | saved_sun / burn_alternative_sun × 100, two decimals. Negative together with saved_sun. |
Order detail
GET /v1/orders/{orderId} · getOrder
Auth: API key (HMAC).
The order plus two breakdowns only this endpoint carries. fills is the priced walk:
how much came from each price class and at what unit price. delegations is what reached
the receiver on chain: one row per delegation with its tx id. No supplier is named.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
orderId | path | string | yes | Either the platform order id (ord_…) or, prefixed with cid:, your own client_order_id — e.g. cid:acme-2026-09-11-000418. The second form saves you from storing our id at all. |
Responses
| Status | Meaning |
|---|---|
200 | OK |
401 | Missing, malformed or rejected credentials. |
404 | No such object, or it belongs to another account. The two are not distinguished. |
429 | Too many requests. |
500 | Something broke on our side. |
Response fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
client_order_id | string | null | ||
group_id | string | null | The group_id you sent with the order, or null. | |
label | string | null | The label you sent with the order, or null. | |
release_when_used_pct | integer | null | The early-release threshold you set, or null (held for the full term). | |
whole_only | boolean | The order is filled by one order at one provider, never in parts (whole_only on create or quote). | |
account_id | string | yes | |
batch_id | string | null | Set when the order was produced by a batch. | |
subscription_id | string | null | Set when the order was produced by a subscription refill. | |
resource | enum: energy, bandwidth, activation | yes | energy — TRON energy, the resource a TRC-20 transfer consumes. · bandwidth — TRON bandwidth (net), consumed by transaction size. · activation — one-off account activation; amount and tier do not apply. |
amount | integer | null | What was ordered. | |
delivered_amount | integer | null | What was actually delegated. Equal to amount or slightly above it on a normal order (a delegation from stake is rounded up by a small margin so the receiver never gets less); below it when partial is true. null until delivery. Mirrors BatchItem.delivered_amount. | |
partial | boolean | True when some allocations landed and some did not, so the receiver got delivered_amount instead of amount and the difference was refunded pro rata (see refunded_amount_sun). Partial delivery is a field, not an order state: the order still runs through confirmed → active. A client that ignores this field sees a delivered order, which is why it defaults to false and is always present once the order has been delivered. | |
tier | enum (14 values, Tier) | null | ||
filled_tier | enum (14 values, Tier) | null | The term actually bought. An order is filled by the cheapest provider term not shorter than tier, so this can be longer than tier (a 5-minute order filled with 15 minutes) and never shorter. When parts of an order were bought at different terms, the shortest of them. null until a part is placed, and on orders placed before this field existed (their term is tier). expires_at follows the term bought. | |
duration_seconds | integer | null | The tier expressed in seconds, so a client need not parse the slug. | |
receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
source | enum: api, dashboard, transfer, bot, subscription, batch, proxy, x402, promo, activation | Where the order came from. transfer is a direct-transfer purchase with no account; x402 is a purchase paid with USDC on Base through x402, also with no account; promo is the free grant of the promo token redeem, no payment and no account. activation is an internal rental onto one of our activator contract’s callers, no payment and no account; customers never see one. | |
status | enum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refunded | yes | The one order state machine, spelled identically in this contract, Webhooks and the dashboard: |
confirm_status | enum: unconfirmed, confirmed, confirm_failed | yes | On-chain confirmation of the delegation, independent of the order’s business state. unconfirmed means the transaction has not been seen in a block yet — it is not a failure. |
price_sun_per_unit | integer | null | ||
pay_amount_sun | integer (int64) | Charged for the resource itself. | |
activate_amount_sun | integer (int64) | Charged for activating the receiver; 0 when no activation was needed. | |
total_amount_sun | integer (int64) | yes | pay_amount_sun + activate_amount_sun. What left the balance. |
provider_amount_sun | integer | null | The provider price inside total_amount_sun, before the service fee. null on lines priced without a fee (orders before 2026-10-06, bandwidth, activation, contract prices). | |
fee | object (ServiceFee) | null | ||
fee.bps | integer | yes | Basis points of the provider price: 500 = 5 %. |
fee.amount_sun | integer (int64) | yes | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. |
fee.source | enum: tier, promo | yes | |
refunded_amount_sun | integer (int64) | Credited back so far. Non-zero for failed and refunded orders. | |
delegate_hash | string | null | First delegation transaction. Convenience field — identical to delegate_hashes[0]. null until the delegation is broadcast. | |
delegate_hashes | array of string | All delegation transactions for this order. More than one when the amount was filled from several stake addresses. Always present, possibly empty. | |
delegated_at | string (date-time) | null | ||
reclaim_hash | string | null | ||
reclaimed_at | string (date-time) | null | ||
expires_at | string (date-time) | null | When the rental window ends. null until delegation. | |
activation | object | What happened about activating the receiver. | |
activation.performed | boolean | ||
activation.hash | string | null | ||
activation.amount_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
memo | string | null | ||
created_at | string (date-time) | yes | |
updated_at | string (date-time) | ||
failure | null | object | Present and non-null only for failed orders. | |
failure.code | integer | yes | |
failure.slug | string | yes | |
failure.message | string | yes | |
failure.at | string (date-time) | ||
savings | null | object (OrderSavings) | The savings receipt: what this order cost against burning TRX for the same energy. null until the delegation is confirmed (confirmed, active, expired, reclaimed), for bandwidth and activation orders, and when the chain’s energy fee could not be read. | |
savings.burn_alternative_sun | integer (int64) | yes | delivered_amount × the chain parameter getEnergyFee — the TRX the receiver would have burned for the same energy. The fee is the chain’s current value on API reads and the value at confirmation in the order.confirmed webhook; it changes only by a Super Representative vote. |
savings.paid_sun | integer | yes | total_amount_sun − refunded_amount_sun: what the order cost net of refunds. |
savings.saved_sun | integer | yes | burn_alternative_sun − paid_sun. Negative when the order cost more than burning; never clamped. |
savings.saved_pct | number | yes | saved_sun / burn_alternative_sun × 100, two decimals. Negative together with saved_sun. |
fills | array of object | yes | |
fills[].class | enum: instant, market, deep | yes | |
fills[].amount | integer | yes | Units priced in this class. |
fills[].price_sun | number | null | yes | SUN per unit; null when unreadable. |
delegations | array of object | yes | |
delegations[].amount | integer | yes | Units delivered (requested until confirmed). |
delegations[].tx_id | string | yes | Delegation transaction id. |
Return the resource before expiry
POST /v1/orders/{orderId}/reclaim · reclaimOrder
Auth: API key (HMAC).
Undelegates the resource early. Useful once the transaction you rented for has landed: the energy stops sitting idle and the inventory can serve someone else.
No refund. Renting and returning are separate operations; returning early does not undo the payment. Reclaim exists so that high-volume users free inventory, not to buy time back.
Idempotent. Calling it twice returns the same reclaim_hash and changes nothing. An
order that already expired on its own also answers 200.
Per order, not per address. One address may hold resource from several orders, possibly belonging to other accounts. To free an address completely, reclaim each of its orders.
Orders filled from a third-party provider instead of our own stake cannot be reclaimed —
those resources are not ours to return. Such an order answers 3008 reclaim_unavailable.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
orderId | path | string | yes | |
Idempotency-Key | header | string | Client-chosen key making this mutating request safe to retry, 8–128 characters of A-Z a-z 0-9 . _ : -. A repeat with the same key and the same body returns the original result; the same key with a different body is rejected with 3010 idempotency_conflict. Records live for 24 hours. |
Responses
| Status | Meaning |
|---|---|
200 | Reclaimed, or already reclaimed. |
202 | Reclaim accepted but the on-chain transaction had not appeared before the response was written. It will almost certainly land on its own — repeat the call in a few seconds to collect the hash, or wait for the order.reclaimed webhook. |
401 | Missing, malformed or rejected credentials. |
404 | No such object, or it belongs to another account. The two are not distinguished. |
409 | Nothing to reclaim (3007) or the order was filled by a third-party provider (3008). |
429 | Too many requests. |
500 | Something broke on our side. |
Response fields (Order)
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
client_order_id | string | null | ||
group_id | string | null | The group_id you sent with the order, or null. | |
label | string | null | The label you sent with the order, or null. | |
release_when_used_pct | integer | null | The early-release threshold you set, or null (held for the full term). | |
whole_only | boolean | The order is filled by one order at one provider, never in parts (whole_only on create or quote). | |
account_id | string | yes | |
batch_id | string | null | Set when the order was produced by a batch. | |
subscription_id | string | null | Set when the order was produced by a subscription refill. | |
resource | enum: energy, bandwidth, activation | yes | energy — TRON energy, the resource a TRC-20 transfer consumes. · bandwidth — TRON bandwidth (net), consumed by transaction size. · activation — one-off account activation; amount and tier do not apply. |
amount | integer | null | What was ordered. | |
delivered_amount | integer | null | What was actually delegated. Equal to amount or slightly above it on a normal order (a delegation from stake is rounded up by a small margin so the receiver never gets less); below it when partial is true. null until delivery. Mirrors BatchItem.delivered_amount. | |
partial | boolean | True when some allocations landed and some did not, so the receiver got delivered_amount instead of amount and the difference was refunded pro rata (see refunded_amount_sun). Partial delivery is a field, not an order state: the order still runs through confirmed → active. A client that ignores this field sees a delivered order, which is why it defaults to false and is always present once the order has been delivered. | |
tier | enum (14 values, Tier) | null | ||
filled_tier | enum (14 values, Tier) | null | The term actually bought. An order is filled by the cheapest provider term not shorter than tier, so this can be longer than tier (a 5-minute order filled with 15 minutes) and never shorter. When parts of an order were bought at different terms, the shortest of them. null until a part is placed, and on orders placed before this field existed (their term is tier). expires_at follows the term bought. | |
duration_seconds | integer | null | The tier expressed in seconds, so a client need not parse the slug. | |
receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
source | enum: api, dashboard, transfer, bot, subscription, batch, proxy, x402, promo, activation | Where the order came from. transfer is a direct-transfer purchase with no account; x402 is a purchase paid with USDC on Base through x402, also with no account; promo is the free grant of the promo token redeem, no payment and no account. activation is an internal rental onto one of our activator contract’s callers, no payment and no account; customers never see one. | |
status | enum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refunded | yes | The one order state machine, spelled identically in this contract, Webhooks and the dashboard: |
confirm_status | enum: unconfirmed, confirmed, confirm_failed | yes | On-chain confirmation of the delegation, independent of the order’s business state. unconfirmed means the transaction has not been seen in a block yet — it is not a failure. |
price_sun_per_unit | integer | null | ||
pay_amount_sun | integer (int64) | Charged for the resource itself. | |
activate_amount_sun | integer (int64) | Charged for activating the receiver; 0 when no activation was needed. | |
total_amount_sun | integer (int64) | yes | pay_amount_sun + activate_amount_sun. What left the balance. |
provider_amount_sun | integer | null | The provider price inside total_amount_sun, before the service fee. null on lines priced without a fee (orders before 2026-10-06, bandwidth, activation, contract prices). | |
fee | object (ServiceFee) | null | ||
fee.bps | integer | yes | Basis points of the provider price: 500 = 5 %. |
fee.amount_sun | integer (int64) | yes | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. |
fee.source | enum: tier, promo | yes | |
refunded_amount_sun | integer (int64) | Credited back so far. Non-zero for failed and refunded orders. | |
delegate_hash | string | null | First delegation transaction. Convenience field — identical to delegate_hashes[0]. null until the delegation is broadcast. | |
delegate_hashes | array of string | All delegation transactions for this order. More than one when the amount was filled from several stake addresses. Always present, possibly empty. | |
delegated_at | string (date-time) | null | ||
reclaim_hash | string | null | ||
reclaimed_at | string (date-time) | null | ||
expires_at | string (date-time) | null | When the rental window ends. null until delegation. | |
activation | object | What happened about activating the receiver. | |
activation.performed | boolean | ||
activation.hash | string | null | ||
activation.amount_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
memo | string | null | ||
created_at | string (date-time) | yes | |
updated_at | string (date-time) | ||
failure | null | object | Present and non-null only for failed orders. | |
failure.code | integer | yes | |
failure.slug | string | yes | |
failure.message | string | yes | |
failure.at | string (date-time) | ||
savings | null | object (OrderSavings) | The savings receipt: what this order cost against burning TRX for the same energy. null until the delegation is confirmed (confirmed, active, expired, reclaimed), for bandwidth and activation orders, and when the chain’s energy fee could not be read. | |
savings.burn_alternative_sun | integer (int64) | yes | delivered_amount × the chain parameter getEnergyFee — the TRX the receiver would have burned for the same energy. The fee is the chain’s current value on API reads and the value at confirmation in the order.confirmed webhook; it changes only by a Super Representative vote. |
savings.paid_sun | integer | yes | total_amount_sun − refunded_amount_sun: what the order cost net of refunds. |
savings.saved_sun | integer | yes | burn_alternative_sun − paid_sun. Negative when the order cost more than burning; never clamped. |
savings.saved_pct | number | yes | saved_sun / burn_alternative_sun × 100, two decimals. Negative together with saved_sun. |
Example 200 response, from the contract (illustrative values — live numbers come from the API):
{
"id": "ord_01J9Z5P8T3WQ",
"client_order_id": "acme-2026-09-11-000418",
"account_id": "acc_01J9Z4K2M7Q8",
"resource": "energy",
"amount": 65000,
"delivered_amount": 65000,
"partial": false,
"tier": "1h",
"duration_seconds": 3600,
"receiver": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"source": "api",
"status": "reclaimed",
"confirm_status": "confirmed",
"price_sun_per_unit": 20,
"pay_amount_sun": 1300000,
"activate_amount_sun": 0,
"total_amount_sun": 1300000,
"refunded_amount_sun": 0,
"delegate_hash": "a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90",
"delegate_hashes": ["a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90"],
"delegated_at": "2026-09-11T18:04:07.900Z",
"reclaim_hash": "51fa77da06e8fbebf504fbf088d1d9611059398d51fa77da06e8fbebf504fbf0",
"reclaimed_at": "2026-09-11T18:12:31.000Z",
"expires_at": "2026-09-11T19:04:07.900Z",
"activation": {"performed":false,"hash":null,"amount_sun":0},
"created_at": "2026-09-11T18:04:05.400Z",
"updated_at": "2026-09-11T18:12:31.000Z",
"failure": null
}