Docs menu

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.

MethodPathSummary
GET/v1/ordersList orders
POST/v1/ordersCreate an order
GET/v1/orders/{orderId}Order detail
POST/v1/orders/{orderId}/reclaimReturn 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

NameInTypeRequiredDescription
statusqueryarray of enum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refundedRepeat the parameter to match several states.
resourcequeryenum: energy, bandwidth, activation
receiverquerystring
client_order_idquerystringExact match. The fastest way to find an order after a lost response.
group_idquerystringExact match on the order’s group_id — every order of one payout run, customer or batch of yours.
labelquerystringExact match on the order’s label.
created_afterquerystring (date-time)
created_beforequerystring (date-time)
fromquerystring (date-time)Inclusive lower bound on created_at — the dashboard’s date range.
toquerystring (date-time)Exclusive upper bound on created_at.
formatqueryenum: json, csv
limitqueryinteger
cursorquerystringOpaque cursor from a previous response’s next_cursor.

Responses

StatusMeaning
200OK
400Malformed request — bad JSON, unknown field, wrong type.
401Missing, malformed or rejected credentials.
429Too many requests.
500Something broke on our side.

Response fields

FieldTypeRequiredDescription
dataarray of object (Order)yes
data[].idstringyes
data[].client_order_idstring | null
data[].group_idstring | nullThe group_id you sent with the order, or null.
data[].labelstring | nullThe label you sent with the order, or null.
data[].release_when_used_pctinteger | nullThe early-release threshold you set, or null (held for the full term).
data[].whole_onlybooleanThe order is filled by one order at one provider, never in parts (whole_only on create or quote).
data[].account_idstringyes
data[].batch_idstring | nullSet when the order was produced by a batch.
data[].subscription_idstring | nullSet when the order was produced by a subscription refill.
data[].resourceenum: energy, bandwidth, activationyesenergy — 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[].amountinteger | nullWhat was ordered.
data[].delivered_amountinteger | nullWhat 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[].partialbooleanTrue 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[].tierenum (14 values, Tier) | null
data[].filled_tierenum (14 values, Tier) | nullThe 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_secondsinteger | nullThe tier expressed in seconds, so a client need not parse the slug.
data[].receiverstringyesBase58Check TRON address (starts with T, 34 characters).
data[].sourceenum: api, dashboard, transfer, bot, subscription, batch, proxy, x402, promo, activationWhere 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[].statusenum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refundedyesThe one order state machine, spelled identically in this contract, Webhooks and the dashboard:
data[].confirm_statusenum: unconfirmed, confirmed, confirm_failedyesOn-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_unitinteger | null
data[].pay_amount_suninteger (int64)Charged for the resource itself.
data[].activate_amount_suninteger (int64)Charged for activating the receiver; 0 when no activation was needed.
data[].total_amount_suninteger (int64)yespay_amount_sun + activate_amount_sun. What left the balance.
data[].provider_amount_suninteger | nullThe 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[].feeobject (ServiceFee) | null
data[].fee.bpsintegeryesBasis points of the provider price: 500 = 5 %.
data[].fee.amount_suninteger (int64)yesAn amount in SUN (1 TRX = 1 000 000 SUN). Always an integer.
data[].fee.sourceenum: tier, promoyes
data[].refunded_amount_suninteger (int64)Credited back so far. Non-zero for failed and refunded orders.
data[].delegate_hashstring | nullFirst delegation transaction. Convenience field — identical to delegate_hashes[0]. null until the delegation is broadcast.
data[].delegate_hashesarray of stringAll delegation transactions for this order. More than one when the amount was filled from several stake addresses. Always present, possibly empty.
data[].delegated_atstring (date-time) | null
data[].reclaim_hashstring | null
data[].reclaimed_atstring (date-time) | null
data[].expires_atstring (date-time) | nullWhen the rental window ends. null until delegation.
data[].activationobjectWhat happened about activating the receiver.
data[].activation.performedboolean
data[].activation.hashstring | null
data[].activation.amount_suninteger (int64)An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer.
data[].memostring | null
data[].created_atstring (date-time)yes
data[].updated_atstring (date-time)
data[].failurenull | objectPresent and non-null only for failed orders.
data[].failure.codeintegeryes
data[].failure.slugstringyes
data[].failure.messagestringyes
data[].failure.atstring (date-time)
data[].savingsnull | 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_suninteger (int64)yesdelivered_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_sunintegeryestotal_amount_sun − refunded_amount_sun: what the order cost net of refunds.
data[].savings.saved_sunintegeryesburn_alternative_sun − paid_sun. Negative when the order cost more than burning; never clamped.
data[].savings.saved_pctnumberyessaved_sun / burn_alternative_sun × 100, two decimals. Negative together with saved_sun.
next_cursorstring | nullyesPass 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_id you are charged exactly the quote’s total_amount_sun, even if the live price has moved since; without one, the live total. max_price_sun is checked against that charge: above it the order is rejected with 3006 price_above_limit and 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 in total_amount_sun. When no provider fits within it, the order ends failed and 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

NameInTypeRequiredDescription
Idempotency-KeyheaderstringClient-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.

FieldTypeRequiredDescription
client_order_idstringYour 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_idstringA 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).
resourceenum: energy, bandwidth, activationenergy — 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.
amountintegerEnergy or bandwidth units. Omit for activation.
tierenum (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.
receiverstringBase58Check TRON address (starts with T, 34 characters).
activatebooleanActivate 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_suninteger (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).
memostring | nullFree-text note stored with the order and echoed back. Not sent on chain.
group_idstringYour 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.
labelstringA short free label for reports (e.g. “withdrawals”, “shop-eu”). Not unique; filterable like group_id.
release_when_used_pctintegerEarly 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_onlybooleantrue: 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):

json
{
  "client_order_id": "acme-2026-09-11-000418",
  "resource": "energy",
  "amount": 65000,
  "tier": "1h",
  "receiver": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
  "activate": true
}

Responses

StatusMeaning
200The 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.
201Order created and charged.
400Malformed request — bad JSON, unknown field, wrong type.
401Missing, malformed or rejected credentials.
402Not enough balance to cover the order.
409The request contradicts the current state of the object.
422Syntactically valid but semantically impossible.
429Too many requests.
500Something broke on our side.
503Temporarily 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)

FieldTypeRequiredDescription
idstringyes
client_order_idstring | null
group_idstring | nullThe group_id you sent with the order, or null.
labelstring | nullThe label you sent with the order, or null.
release_when_used_pctinteger | nullThe early-release threshold you set, or null (held for the full term).
whole_onlybooleanThe order is filled by one order at one provider, never in parts (whole_only on create or quote).
account_idstringyes
batch_idstring | nullSet when the order was produced by a batch.
subscription_idstring | nullSet when the order was produced by a subscription refill.
resourceenum: energy, bandwidth, activationyesenergy — 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.
amountinteger | nullWhat was ordered.
delivered_amountinteger | nullWhat 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.
partialbooleanTrue 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.
tierenum (14 values, Tier) | null
filled_tierenum (14 values, Tier) | nullThe 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_secondsinteger | nullThe tier expressed in seconds, so a client need not parse the slug.
receiverstringyesBase58Check TRON address (starts with T, 34 characters).
sourceenum: api, dashboard, transfer, bot, subscription, batch, proxy, x402, promo, activationWhere 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.
statusenum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refundedyesThe one order state machine, spelled identically in this contract, Webhooks and the dashboard:
confirm_statusenum: unconfirmed, confirmed, confirm_failedyesOn-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_unitinteger | null
pay_amount_suninteger (int64)Charged for the resource itself.
activate_amount_suninteger (int64)Charged for activating the receiver; 0 when no activation was needed.
total_amount_suninteger (int64)yespay_amount_sun + activate_amount_sun. What left the balance.
provider_amount_suninteger | nullThe 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).
feeobject (ServiceFee) | null
fee.bpsintegeryesBasis points of the provider price: 500 = 5 %.
fee.amount_suninteger (int64)yesAn amount in SUN (1 TRX = 1 000 000 SUN). Always an integer.
fee.sourceenum: tier, promoyes
refunded_amount_suninteger (int64)Credited back so far. Non-zero for failed and refunded orders.
delegate_hashstring | nullFirst delegation transaction. Convenience field — identical to delegate_hashes[0]. null until the delegation is broadcast.
delegate_hashesarray of stringAll delegation transactions for this order. More than one when the amount was filled from several stake addresses. Always present, possibly empty.
delegated_atstring (date-time) | null
reclaim_hashstring | null
reclaimed_atstring (date-time) | null
expires_atstring (date-time) | nullWhen the rental window ends. null until delegation.
activationobjectWhat happened about activating the receiver.
activation.performedboolean
activation.hashstring | null
activation.amount_suninteger (int64)An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer.
memostring | null
created_atstring (date-time)yes
updated_atstring (date-time)
failurenull | objectPresent and non-null only for failed orders.
failure.codeintegeryes
failure.slugstringyes
failure.messagestringyes
failure.atstring (date-time)
savingsnull | 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_suninteger (int64)yesdelivered_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_sunintegeryestotal_amount_sun − refunded_amount_sun: what the order cost net of refunds.
savings.saved_sunintegeryesburn_alternative_sun − paid_sun. Negative when the order cost more than burning; never clamped.
savings.saved_pctnumberyessaved_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

NameInTypeRequiredDescription
orderIdpathstringyesEither 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

StatusMeaning
200OK
401Missing, malformed or rejected credentials.
404No such object, or it belongs to another account. The two are not distinguished.
429Too many requests.
500Something broke on our side.

Response fields

FieldTypeRequiredDescription
idstringyes
client_order_idstring | null
group_idstring | nullThe group_id you sent with the order, or null.
labelstring | nullThe label you sent with the order, or null.
release_when_used_pctinteger | nullThe early-release threshold you set, or null (held for the full term).
whole_onlybooleanThe order is filled by one order at one provider, never in parts (whole_only on create or quote).
account_idstringyes
batch_idstring | nullSet when the order was produced by a batch.
subscription_idstring | nullSet when the order was produced by a subscription refill.
resourceenum: energy, bandwidth, activationyesenergy — 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.
amountinteger | nullWhat was ordered.
delivered_amountinteger | nullWhat 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.
partialbooleanTrue 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.
tierenum (14 values, Tier) | null
filled_tierenum (14 values, Tier) | nullThe 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_secondsinteger | nullThe tier expressed in seconds, so a client need not parse the slug.
receiverstringyesBase58Check TRON address (starts with T, 34 characters).
sourceenum: api, dashboard, transfer, bot, subscription, batch, proxy, x402, promo, activationWhere 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.
statusenum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refundedyesThe one order state machine, spelled identically in this contract, Webhooks and the dashboard:
confirm_statusenum: unconfirmed, confirmed, confirm_failedyesOn-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_unitinteger | null
pay_amount_suninteger (int64)Charged for the resource itself.
activate_amount_suninteger (int64)Charged for activating the receiver; 0 when no activation was needed.
total_amount_suninteger (int64)yespay_amount_sun + activate_amount_sun. What left the balance.
provider_amount_suninteger | nullThe 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).
feeobject (ServiceFee) | null
fee.bpsintegeryesBasis points of the provider price: 500 = 5 %.
fee.amount_suninteger (int64)yesAn amount in SUN (1 TRX = 1 000 000 SUN). Always an integer.
fee.sourceenum: tier, promoyes
refunded_amount_suninteger (int64)Credited back so far. Non-zero for failed and refunded orders.
delegate_hashstring | nullFirst delegation transaction. Convenience field — identical to delegate_hashes[0]. null until the delegation is broadcast.
delegate_hashesarray of stringAll delegation transactions for this order. More than one when the amount was filled from several stake addresses. Always present, possibly empty.
delegated_atstring (date-time) | null
reclaim_hashstring | null
reclaimed_atstring (date-time) | null
expires_atstring (date-time) | nullWhen the rental window ends. null until delegation.
activationobjectWhat happened about activating the receiver.
activation.performedboolean
activation.hashstring | null
activation.amount_suninteger (int64)An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer.
memostring | null
created_atstring (date-time)yes
updated_atstring (date-time)
failurenull | objectPresent and non-null only for failed orders.
failure.codeintegeryes
failure.slugstringyes
failure.messagestringyes
failure.atstring (date-time)
savingsnull | 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_suninteger (int64)yesdelivered_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_sunintegeryestotal_amount_sun − refunded_amount_sun: what the order cost net of refunds.
savings.saved_sunintegeryesburn_alternative_sun − paid_sun. Negative when the order cost more than burning; never clamped.
savings.saved_pctnumberyessaved_sun / burn_alternative_sun × 100, two decimals. Negative together with saved_sun.
fillsarray of objectyes
fills[].classenum: instant, market, deepyes
fills[].amountintegeryesUnits priced in this class.
fills[].price_sunnumber | nullyesSUN per unit; null when unreadable.
delegationsarray of objectyes
delegations[].amountintegeryesUnits delivered (requested until confirmed).
delegations[].tx_idstringyesDelegation 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

NameInTypeRequiredDescription
orderIdpathstringyes
Idempotency-KeyheaderstringClient-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

StatusMeaning
200Reclaimed, or already reclaimed.
202Reclaim 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.
401Missing, malformed or rejected credentials.
404No such object, or it belongs to another account. The two are not distinguished.
409Nothing to reclaim (3007) or the order was filled by a third-party provider (3008).
429Too many requests.
500Something broke on our side.

Response fields (Order)

FieldTypeRequiredDescription
idstringyes
client_order_idstring | null
group_idstring | nullThe group_id you sent with the order, or null.
labelstring | nullThe label you sent with the order, or null.
release_when_used_pctinteger | nullThe early-release threshold you set, or null (held for the full term).
whole_onlybooleanThe order is filled by one order at one provider, never in parts (whole_only on create or quote).
account_idstringyes
batch_idstring | nullSet when the order was produced by a batch.
subscription_idstring | nullSet when the order was produced by a subscription refill.
resourceenum: energy, bandwidth, activationyesenergy — 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.
amountinteger | nullWhat was ordered.
delivered_amountinteger | nullWhat 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.
partialbooleanTrue 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.
tierenum (14 values, Tier) | null
filled_tierenum (14 values, Tier) | nullThe 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_secondsinteger | nullThe tier expressed in seconds, so a client need not parse the slug.
receiverstringyesBase58Check TRON address (starts with T, 34 characters).
sourceenum: api, dashboard, transfer, bot, subscription, batch, proxy, x402, promo, activationWhere 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.
statusenum: created, paid, allocating, delegated, confirmed, active, expired, reclaimed, failed, refundedyesThe one order state machine, spelled identically in this contract, Webhooks and the dashboard:
confirm_statusenum: unconfirmed, confirmed, confirm_failedyesOn-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_unitinteger | null
pay_amount_suninteger (int64)Charged for the resource itself.
activate_amount_suninteger (int64)Charged for activating the receiver; 0 when no activation was needed.
total_amount_suninteger (int64)yespay_amount_sun + activate_amount_sun. What left the balance.
provider_amount_suninteger | nullThe 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).
feeobject (ServiceFee) | null
fee.bpsintegeryesBasis points of the provider price: 500 = 5 %.
fee.amount_suninteger (int64)yesAn amount in SUN (1 TRX = 1 000 000 SUN). Always an integer.
fee.sourceenum: tier, promoyes
refunded_amount_suninteger (int64)Credited back so far. Non-zero for failed and refunded orders.
delegate_hashstring | nullFirst delegation transaction. Convenience field — identical to delegate_hashes[0]. null until the delegation is broadcast.
delegate_hashesarray of stringAll delegation transactions for this order. More than one when the amount was filled from several stake addresses. Always present, possibly empty.
delegated_atstring (date-time) | null
reclaim_hashstring | null
reclaimed_atstring (date-time) | null
expires_atstring (date-time) | nullWhen the rental window ends. null until delegation.
activationobjectWhat happened about activating the receiver.
activation.performedboolean
activation.hashstring | null
activation.amount_suninteger (int64)An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer.
memostring | null
created_atstring (date-time)yes
updated_atstring (date-time)
failurenull | objectPresent and non-null only for failed orders.
failure.codeintegeryes
failure.slugstringyes
failure.messagestringyes
failure.atstring (date-time)
savingsnull | 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_suninteger (int64)yesdelivered_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_sunintegeryestotal_amount_sun − refunded_amount_sun: what the order cost net of refunds.
savings.saved_sunintegeryesburn_alternative_sun − paid_sun. Negative when the order cost more than burning; never clamped.
savings.saved_pctnumberyessaved_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):

json
{
  "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
}

    ↑ ↓ to move · Enter to open · Esc to close