Batches — API reference
One request, many receivers.
| Method | Path | Summary |
|---|---|---|
GET | /v1/batches | List batches |
POST | /v1/batches | Order for many receivers in one call |
GET | /v1/batches/{batchId} | Batch progress |
POST | /v1/batches/{batchId}/cancel | Cancel the not-yet-started part of a batch |
Generated from openapi.yaml at build time. 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 batches
GET /v1/batches · listBatches
Auth: API key (HMAC).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | ||
cursor | query | string | Opaque cursor from a previous response’s next_cursor. |
Responses
| Status | Meaning |
|---|---|
200 | OK |
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 (Batch) | yes | |
data[].id | string | yes | |
data[].client_batch_id | string | null | ||
data[].status | enum: queued, processing, completed, partial, failed, cancelled | yes | The batch’s own state, derived from its items. partial means some receivers succeeded and some did not — inspect items, never assume all-or-nothing. |
data[].items_accepted | integer | yes | |
data[].summary | object | yes | Counts by item status. Cheaper to poll than the full item list. |
data[].summary.total | integer | ||
data[].summary.queued | integer | ||
data[].summary.processing | integer | ||
data[].summary.completed | integer | ||
data[].summary.partial | integer | ||
data[].summary.failed | integer | ||
data[].summary.insufficient_funds | integer | ||
data[].summary.cancelled | integer | ||
data[].items | array of object (BatchItem) | yes | |
data[].items[].receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
data[].items[].tracking_id | string | yes | <client_batch_id>:<receiver> — the identity of one receiver in one batch. |
data[].items[].status | enum: queued, processing, completed, partial, failed, insufficient_funds, cancelled | yes | |
data[].items[].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. | |
data[].items[].amount | integer | ||
data[].items[].tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | Rental period. The API sells 5m and 1h; 1d exists but is switched off. 15m, 3d and 30d are retired and never sold — they stay in the enum only so old orders parse. Check available on each GET /v1/prices row; a tier that is not available is rejected with 2003 tier_unavailable. | |
data[].items[].delivered_amount | integer | How much was actually delegated. Below amount when status is partial. | |
data[].items[].order_ids | array of string | The orders created for this receiver — more than one when a large amount was chunked. These are ordinary orders: inspect and reclaim them individually. | |
data[].items[].delegate_hashes | array of string | ||
data[].items[].charged_amount_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
data[].items[].activation | object | ||
data[].items[].bandwidth | object | ||
data[].items[].attempts | integer | ||
data[].items[].started_at | string (date-time) | null | ||
data[].items[].finished_at | string (date-time) | null | ||
data[].items[].failure | null | object | ||
data[].created_at | string (date-time) | yes | |
data[].finished_at | string (date-time) | null | ||
next_cursor | string | null | yes |
Order for many receivers in one call
POST /v1/batches · createBatch
Auth: API key (HMAC).
Up to 100 receivers per request. For each receiver the platform runs the whole sequence — activate the address if it is not active, top up its bandwidth if it is short, then deliver the resource, splitting large amounts into chunks automatically.
The response is 202 Accepted: the batch is queued, nothing is charged yet, and
nothing has been delivered. Read the result from GET /v1/batches/{id} or from the
per-order webhooks.
One receiver failing never affects the others, and a failed activation or bandwidth step does not stop the resource order for that receiver.
Receivers are billed individually, at the price in force when each one is executed — so a
long batch may span a pricing period boundary. Pass max_price_sun per item to cap that.
Each receiver produces its own order with its own id, which is what you reclaim, inspect
and reconcile against. client_batch_id is the idempotency key for the batch as a whole:
a repeat with the same id and the same body returns the original batch; the same id with a
different body is rejected with 3010 idempotency_conflict.
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 (BatchRequest), required.
| Field | Type | Required | Description |
|---|---|---|---|
client_batch_id | string | Your reference for the batch and its idempotency key. Required unless you send the Idempotency-Key header; with neither the request is rejected with 2005 idempotency_key_required. | |
defaults | object (BatchItemOptions) | Applied to every item that does not override the field itself. | |
defaults.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. | |
defaults.amount | integer | ||
defaults.tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | Rental period. The API sells 5m and 1h; 1d exists but is switched off. 15m, 3d and 30d are retired and never sold — they stay in the enum only so old orders parse. Check available on each GET /v1/prices row; a tier that is not available is rejected with 2003 tier_unavailable. | |
defaults.activate | boolean | ||
defaults.bandwidth | boolean | Top the receiver’s bandwidth up when it is short, before delivering energy. | |
defaults.bandwidth_amount | integer | Bandwidth units to add when the top-up runs. | |
defaults.max_price_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
defaults.client_order_id_prefix | string | When set, each generated order gets client_order_id = "<prefix>-<receiver>", so your side can reconcile without keeping our ids. | |
items | array of object | yes | Duplicate receivers within one batch are rejected with 2006 duplicate_receiver. |
items[].receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
items[].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. | |
items[].amount | integer | ||
items[].tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | Rental period. The API sells 5m and 1h; 1d exists but is switched off. 15m, 3d and 30d are retired and never sold — they stay in the enum only so old orders parse. Check available on each GET /v1/prices row; a tier that is not available is rejected with 2003 tier_unavailable. | |
items[].activate | boolean | ||
items[].bandwidth | boolean | Top the receiver’s bandwidth up when it is short, before delivering energy. | |
items[].bandwidth_amount | integer | Bandwidth units to add when the top-up runs. | |
items[].max_price_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
items[].client_order_id_prefix | string | When set, each generated order gets client_order_id = "<prefix>-<receiver>", so your side can reconcile without keeping our ids. |
Example request body, from the contract (illustrative values):
{
"client_batch_id": "acme-payout-2026-09-11-01",
"defaults": {
"resource": "energy",
"tier": "1h",
"amount": 65000,
"activate": true,
"bandwidth": true,
"bandwidth_amount": 400
},
"items": [
{"receiver":"TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"},
{"receiver":"TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","amount":131000},
{"receiver":"TYYyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy","bandwidth":false}
]
}
Responses
| Status | Meaning |
|---|---|
200 | Same client_batch_id and same body — the original batch is returned. |
202 | Batch accepted and queued. Nothing charged yet. |
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 (Batch)
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
client_batch_id | string | null | ||
status | enum: queued, processing, completed, partial, failed, cancelled | yes | The batch’s own state, derived from its items. partial means some receivers succeeded and some did not — inspect items, never assume all-or-nothing. |
items_accepted | integer | yes | |
summary | object | yes | Counts by item status. Cheaper to poll than the full item list. |
summary.total | integer | ||
summary.queued | integer | ||
summary.processing | integer | ||
summary.completed | integer | ||
summary.partial | integer | ||
summary.failed | integer | ||
summary.insufficient_funds | integer | ||
summary.cancelled | integer | ||
items | array of object (BatchItem) | yes | |
items[].receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
items[].tracking_id | string | yes | <client_batch_id>:<receiver> — the identity of one receiver in one batch. |
items[].status | enum: queued, processing, completed, partial, failed, insufficient_funds, cancelled | yes | |
items[].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. | |
items[].amount | integer | ||
items[].tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | Rental period. The API sells 5m and 1h; 1d exists but is switched off. 15m, 3d and 30d are retired and never sold — they stay in the enum only so old orders parse. Check available on each GET /v1/prices row; a tier that is not available is rejected with 2003 tier_unavailable. | |
items[].delivered_amount | integer | How much was actually delegated. Below amount when status is partial. | |
items[].order_ids | array of string | The orders created for this receiver — more than one when a large amount was chunked. These are ordinary orders: inspect and reclaim them individually. | |
items[].delegate_hashes | array of string | ||
items[].charged_amount_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
items[].activation | object | ||
items[].activation.status | enum: planned, not_needed, done, failed, skipped | ||
items[].activation.hash | string | null | ||
items[].bandwidth | object | ||
items[].bandwidth.status | enum: planned, enough, done, failed, skipped | ||
items[].bandwidth.order_id | string | null | ||
items[].bandwidth.skip_reason | enum: option_off, amount_large | null | Why the bandwidth step did not run. option_off — you disabled it; amount_large — a large energy order does not need a bandwidth top-up. | |
items[].attempts | integer | ||
items[].started_at | string (date-time) | null | ||
items[].finished_at | string (date-time) | null | ||
items[].failure | null | object | ||
items[].failure.code | integer | ||
items[].failure.slug | string | ||
items[].failure.message | string | ||
created_at | string (date-time) | yes | |
finished_at | string (date-time) | null |
Batch progress
GET /v1/batches/{batchId} · getBatch
Auth: API key (HMAC).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
batchId | path | string | yes | Platform id (bat_…) or cid:<client_batch_id>. |
receiver | query | string | Return only the item for this address instead of the whole batch. |
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 (Batch)
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
client_batch_id | string | null | ||
status | enum: queued, processing, completed, partial, failed, cancelled | yes | The batch’s own state, derived from its items. partial means some receivers succeeded and some did not — inspect items, never assume all-or-nothing. |
items_accepted | integer | yes | |
summary | object | yes | Counts by item status. Cheaper to poll than the full item list. |
summary.total | integer | ||
summary.queued | integer | ||
summary.processing | integer | ||
summary.completed | integer | ||
summary.partial | integer | ||
summary.failed | integer | ||
summary.insufficient_funds | integer | ||
summary.cancelled | integer | ||
items | array of object (BatchItem) | yes | |
items[].receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
items[].tracking_id | string | yes | <client_batch_id>:<receiver> — the identity of one receiver in one batch. |
items[].status | enum: queued, processing, completed, partial, failed, insufficient_funds, cancelled | yes | |
items[].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. | |
items[].amount | integer | ||
items[].tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | Rental period. The API sells 5m and 1h; 1d exists but is switched off. 15m, 3d and 30d are retired and never sold — they stay in the enum only so old orders parse. Check available on each GET /v1/prices row; a tier that is not available is rejected with 2003 tier_unavailable. | |
items[].delivered_amount | integer | How much was actually delegated. Below amount when status is partial. | |
items[].order_ids | array of string | The orders created for this receiver — more than one when a large amount was chunked. These are ordinary orders: inspect and reclaim them individually. | |
items[].delegate_hashes | array of string | ||
items[].charged_amount_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
items[].activation | object | ||
items[].activation.status | enum: planned, not_needed, done, failed, skipped | ||
items[].activation.hash | string | null | ||
items[].bandwidth | object | ||
items[].bandwidth.status | enum: planned, enough, done, failed, skipped | ||
items[].bandwidth.order_id | string | null | ||
items[].bandwidth.skip_reason | enum: option_off, amount_large | null | Why the bandwidth step did not run. option_off — you disabled it; amount_large — a large energy order does not need a bandwidth top-up. | |
items[].attempts | integer | ||
items[].started_at | string (date-time) | null | ||
items[].finished_at | string (date-time) | null | ||
items[].failure | null | object | ||
items[].failure.code | integer | ||
items[].failure.slug | string | ||
items[].failure.message | string | ||
created_at | string (date-time) | yes | |
finished_at | string (date-time) | null |
Cancel the not-yet-started part of a batch
POST /v1/batches/{batchId}/cancel · cancelBatch
Auth: API key (HMAC).
Removes from the queue every receiver that has not been picked up yet. Receivers already being processed are not interrupted — part of their resource may already be paid for. Cancel is best-effort on the remainder.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
batchId | path | string | yes |
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 | |
cancelled | integer | yes | How many receivers were removed from the queue. |