Subscriptions — API reference
Auto-refill for an address.
| Method | Path | Summary |
|---|---|---|
GET | /v1/subscriptions/plans | Subscription presets, limits and the fee rule |
GET | /v1/subscriptions | List subscriptions |
POST | /v1/subscriptions | Auto-refill an address |
GET | /v1/subscriptions/{subscriptionId} | Read a subscription |
PATCH | /v1/subscriptions/{subscriptionId} | Change or pause a subscription |
DELETE | /v1/subscriptions/{subscriptionId} | Cancel a subscription |
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.
Subscription presets, limits and the fee rule
GET /v1/subscriptions/plans · listSubscriptionPlans
Auth: Public — no credentials.
Public; an API key is verified when presented. A preset only fills reserve, low and
high; any rule inside limits is accepted (PlanSubscriptionRequest). Fee per day =
ceil(reserve × fee_rule.trx_per_unit / fee_rule.unit_energy) whole TRX. Refills in every
plan are priced at the 1 h grid of the current day-part (per_use). average_price is
computed server-side for 10/50/200/1,000 uses a day.
Responses
| Status | Meaning |
|---|---|
200 | Active plans, smallest reserve first. |
Response fields
| Field | Type | Required | Description |
|---|---|---|---|
available | boolean | yes | False while subscriptions are switched off on this deployment; the plans are shown, not sold. |
data | array of object (SubscriptionPlan) | yes | |
data[].slug | string | yes | |
data[].name | string | yes | |
data[].reserve | integer | yes | Energy kept delegated to the address at most. |
data[].low | integer | yes | Refill when available energy falls below this. |
data[].high | integer | yes | Refill up to this. |
data[].fee_sun_per_day | integer | yes | |
data[].fee_trx_per_day | number | yes | |
data[].throughput_rule | string | yes | |
data[].uses_within_reserve_per_day | integer | yes | |
data[].average_price | array of object | yes | Average price per use = daily fee / N + per-use price, for N = 10, 50, 200, 1,000. |
data[].average_price[].uses_per_day | integer | yes | |
data[].average_price[].average_sun | integer | null | yes | |
data[].average_price[].average_trx | number | null | yes | |
data[].average_price[].within_reserve | boolean | yes | |
per_use | object | yes | |
per_use.mode | enum: grid | yes | The 1 h energy price of the current day-part × 65,000. |
per_use.energy_per_use | integer | yes | |
per_use.price_sun | integer | null | yes | null while 1 h energy is paused. |
per_use.price_trx | number | null | yes | |
per_use.day_part | string | null | yes | Day-part window id. |
limits | object | yes | 131,000 ≤ reserve ≤ 5,240,000; each number a multiple of step; low ≥ low_min; low < high ≤ reserve; high − low ≥ gap_min. Exception: low = high = reserve = 131,000 (Basic). |
limits.reserve_min | integer | yes | |
limits.reserve_max | integer | yes | |
limits.step | integer | yes | |
limits.low_min | integer | yes | |
limits.gap_min | integer | yes | |
fee_rule | object | yes | |
fee_rule.trx_per_unit | integer | yes | |
fee_rule.unit_energy | integer | yes | |
fee_rule.rounding | enum: ceil_whole_trx | yes | |
at | string (date-time) | yes |
List subscriptions
GET /v1/subscriptions · listSubscriptions
Auth: API key (HMAC).
Scope subscriptions.read, or a dashboard session with member role viewer.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | enum: active, paused, suspended, cancelled | ||
receiver | query | string | ||
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 (Subscription) | yes | |
data[].id | string | yes | |
data[].receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
data[].resource | enum: energy, bandwidth | yes | |
data[].mode | enum: refill, renewal | yes | |
data[].tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | yes | 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[].threshold_amount | integer | ||
data[].refill_amount | integer | ||
data[].max_price_sun | integer (int64) | null | ||
data[].max_refills_per_day | integer | null | ||
data[].daily_fee_sun | integer (int64) | Watch fee charged per calendar day while the subscription is not cancelled. | |
data[].status | enum: active, paused, suspended, cancelled | yes | paused is set by you; suspended is set by the platform when the balance cannot cover the next refill and clears itself after a deposit; cancelled is terminal. |
data[].label | string | null | ||
data[].last_refill_at | string (date-time) | null | ||
data[].last_order_id | string | null | ||
data[].refills_today | integer | ||
data[].created_at | string (date-time) | yes | |
data[].updated_at | string (date-time) | ||
data[].address | string | Same as receiver. Present only on plan subscriptions, with the fields below. | |
data[].preset | string | null | Preset slug; null for a custom rule. | |
data[].reserve | integer | null | Energy kept delegated at most. | |
data[].low | integer | null | Refill when available energy falls below this. | |
data[].high | integer | null | Refill up to this. | |
data[].fee_trx_per_day | number | ||
data[].delegated_energy | integer | Energy delegated to the address now. | |
data[].next_billing_at | string (date-time) | null | ||
data[].grace_until | string (date-time) | null | Set while a failed daily charge keeps the energy delegated (reported as suspended). | |
data[].events | array of object (SubscriptionEvent) | GET /v1/subscriptions/{id} of a plan subscription only: the last 20 events, newest first. | |
data[].events[].id | string | yes | |
data[].events[].kind | enum: refill, charge, pause, resume, cancel, top_up_failed | yes | |
data[].events[].energy_delta | integer | null | ||
data[].events[].amount_sun | integer | null | ||
data[].events[].txid | string | null | ||
data[].events[].ts | string (date-time) | yes | |
next_cursor | string | null | yes |
Auto-refill an address
POST /v1/subscriptions · createSubscription
Auth: API key (HMAC).
Keeps an address supplied with energy. A subscription is three numbers
(PlanSubscriptionRequest): {address, preset} or {address, reserve, low, high}.
reserve(R) — the energy held for the address; 131,000 ≤ R ≤ 5,240,000, step 1,000.low— refill when the address’s free energy drops below it;low≥ 65,000.high— refill up to it;high − low≥ 65,000 andhigh≤ R. Thebasicpreset (low=high= R) is the one exception.
| Preset | Reserve | Daily fee |
|---|---|---|
basic | 131,000 | 6 TRX |
1.3m | 1,300,000 | 60 TRX |
2.62m | 2,620,000 | 120 TRX |
5.24m | 5,240,000 | 240 TRX |
Billing: the daily fee is ceil(R × 6 / 131,000) whole TRX. The first day is charged when
the subscription starts, then every 24 hours. Each refill is charged at the live 1h
price. A rule outside the limits of GET /v1/subscriptions/plans is 422
3020 subscription_rule_invalid with details.violations. PATCH takes
{reserve, low, high}, {preset} or {status} (PlanSubscriptionPatch).
While GET /v1/subscriptions/plans → available is false this call is 409
3021 subscriptions_unavailable.
One address may have at most one subscription per resource. A second one is rejected with
3011 subscription_exists.
Legacy body: mode: "refill" / mode: "renewal" with threshold_amount is still
accepted for existing integrations; new integrations use the three numbers above. The
201 example shows a legacy subscription; its numbers are illustrative.
Scope subscriptions.write, or a dashboard session with member role editor and
X-CSRF-Token.
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 (SubscriptionRequest), required.
| Field | Type | Required | Description |
|---|---|---|---|
receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
resource | enum: energy, bandwidth | yes | |
mode | enum: refill, renewal | yes | refill tops up when the address falls below the threshold; renewal keeps a standing rental alive by re-ordering as it expires. |
tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | yes | 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. |
threshold_amount | integer | yes | Refill when free resource on the address drops below this. |
refill_amount | integer | yes | How much to buy on each refill. |
max_price_sun | integer (int64) | Skip a refill whose total would exceed this rather than paying a spike price. A skipped refill produces no order and no webhook; the next check tries again. | |
max_refills_per_day | integer | Hard stop against a runaway address draining the balance. Once reached, refills pause until the next UTC day. Strongly recommended. | |
label | string | null |
Example request body, from the contract (illustrative values):
{"address":"TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE","preset":"basic"}
Responses
| Status | Meaning |
|---|---|
201 | Created |
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. |
Response fields (Subscription)
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
resource | enum: energy, bandwidth | yes | |
mode | enum: refill, renewal | yes | |
tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | yes | 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. |
threshold_amount | integer | ||
refill_amount | integer | ||
max_price_sun | integer (int64) | null | ||
max_refills_per_day | integer | null | ||
daily_fee_sun | integer (int64) | Watch fee charged per calendar day while the subscription is not cancelled. | |
status | enum: active, paused, suspended, cancelled | yes | paused is set by you; suspended is set by the platform when the balance cannot cover the next refill and clears itself after a deposit; cancelled is terminal. |
label | string | null | ||
last_refill_at | string (date-time) | null | ||
last_order_id | string | null | ||
refills_today | integer | ||
created_at | string (date-time) | yes | |
updated_at | string (date-time) | ||
address | string | Same as receiver. Present only on plan subscriptions, with the fields below. | |
preset | string | null | Preset slug; null for a custom rule. | |
reserve | integer | null | Energy kept delegated at most. | |
low | integer | null | Refill when available energy falls below this. | |
high | integer | null | Refill up to this. | |
fee_trx_per_day | number | ||
delegated_energy | integer | Energy delegated to the address now. | |
next_billing_at | string (date-time) | null | ||
grace_until | string (date-time) | null | Set while a failed daily charge keeps the energy delegated (reported as suspended). | |
events | array of object (SubscriptionEvent) | GET /v1/subscriptions/{id} of a plan subscription only: the last 20 events, newest first. | |
events[].id | string | yes | |
events[].kind | enum: refill, charge, pause, resume, cancel, top_up_failed | yes | |
events[].energy_delta | integer | null | ||
events[].amount_sun | integer | null | ||
events[].txid | string | null | ||
events[].ts | string (date-time) | yes |
Example 201 response, from the contract (illustrative values — live numbers come from the API):
{
"id": "sub_01J9Z7R4Y2AB",
"receiver": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"resource": "energy",
"mode": "refill",
"tier": "1h",
"threshold_amount": 65000,
"refill_amount": 131000,
"max_price_sun": 3000000,
"max_refills_per_day": 48,
"daily_fee_sun": 3930000,
"status": "active",
"last_refill_at": null,
"last_order_id": null,
"refills_today": 0,
"created_at": "2026-09-11T18:30:00.000Z",
"updated_at": "2026-09-11T18:30:00.000Z"
}
Read a subscription
GET /v1/subscriptions/{subscriptionId} · getSubscription
Auth: API key (HMAC).
Scope subscriptions.read, or a dashboard session with member role viewer. Another
account’s subscription answers 404.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
subscriptionId | 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. |
500 | Something broke on our side. |
Response fields (Subscription)
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
resource | enum: energy, bandwidth | yes | |
mode | enum: refill, renewal | yes | |
tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | yes | 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. |
threshold_amount | integer | ||
refill_amount | integer | ||
max_price_sun | integer (int64) | null | ||
max_refills_per_day | integer | null | ||
daily_fee_sun | integer (int64) | Watch fee charged per calendar day while the subscription is not cancelled. | |
status | enum: active, paused, suspended, cancelled | yes | paused is set by you; suspended is set by the platform when the balance cannot cover the next refill and clears itself after a deposit; cancelled is terminal. |
label | string | null | ||
last_refill_at | string (date-time) | null | ||
last_order_id | string | null | ||
refills_today | integer | ||
created_at | string (date-time) | yes | |
updated_at | string (date-time) | ||
address | string | Same as receiver. Present only on plan subscriptions, with the fields below. | |
preset | string | null | Preset slug; null for a custom rule. | |
reserve | integer | null | Energy kept delegated at most. | |
low | integer | null | Refill when available energy falls below this. | |
high | integer | null | Refill up to this. | |
fee_trx_per_day | number | ||
delegated_energy | integer | Energy delegated to the address now. | |
next_billing_at | string (date-time) | null | ||
grace_until | string (date-time) | null | Set while a failed daily charge keeps the energy delegated (reported as suspended). | |
events | array of object (SubscriptionEvent) | GET /v1/subscriptions/{id} of a plan subscription only: the last 20 events, newest first. | |
events[].id | string | yes | |
events[].kind | enum: refill, charge, pause, resume, cancel, top_up_failed | yes | |
events[].energy_delta | integer | null | ||
events[].amount_sun | integer | null | ||
events[].txid | string | null | ||
events[].ts | string (date-time) | yes |
Change or pause a subscription
PATCH /v1/subscriptions/{subscriptionId} · updateSubscription
Auth: API key (HMAC).
Send any subset of the mutable fields. status accepts active and paused only —
suspended is set by the platform when funds run out and clears itself, and cancelled
is reached through DELETE. An empty body is rejected with 2002 empty_patch.
While subscriptions are switched off, a patch that changes the rule, preset or refill
parameters is 409 3021 subscriptions_unavailable; status, label, reads and
DELETE keep working so existing subscriptions can be managed.
Scope subscriptions.write, or a dashboard session with member role editor and
X-CSRF-Token.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
subscriptionId | path | string | yes |
Request body
JSON (SubscriptionPatch), required.
| Field | Type | Required | Description |
|---|---|---|---|
status | enum: active, paused | ||
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. | |
threshold_amount | integer | ||
refill_amount | integer | ||
max_price_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
max_refills_per_day | integer | ||
label | string | null |
Example request body, from the contract (illustrative values):
{"status":"paused"}
Responses
| Status | Meaning |
|---|---|
200 | Updated |
400 | Malformed request — bad JSON, unknown field, wrong type. |
401 | Missing, malformed or rejected credentials. |
404 | No such object, or it belongs to another account. The two are not distinguished. |
409 | The request contradicts the current state of the object. |
422 | Syntactically valid but semantically impossible. |
500 | Something broke on our side. |
Response fields (Subscription)
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
receiver | string | yes | Base58Check TRON address (starts with T, 34 characters). |
resource | enum: energy, bandwidth | yes | |
mode | enum: refill, renewal | yes | |
tier | enum: 5m, 15m, 1h, 1d, 3d, 30d | yes | 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. |
threshold_amount | integer | ||
refill_amount | integer | ||
max_price_sun | integer (int64) | null | ||
max_refills_per_day | integer | null | ||
daily_fee_sun | integer (int64) | Watch fee charged per calendar day while the subscription is not cancelled. | |
status | enum: active, paused, suspended, cancelled | yes | paused is set by you; suspended is set by the platform when the balance cannot cover the next refill and clears itself after a deposit; cancelled is terminal. |
label | string | null | ||
last_refill_at | string (date-time) | null | ||
last_order_id | string | null | ||
refills_today | integer | ||
created_at | string (date-time) | yes | |
updated_at | string (date-time) | ||
address | string | Same as receiver. Present only on plan subscriptions, with the fields below. | |
preset | string | null | Preset slug; null for a custom rule. | |
reserve | integer | null | Energy kept delegated at most. | |
low | integer | null | Refill when available energy falls below this. | |
high | integer | null | Refill up to this. | |
fee_trx_per_day | number | ||
delegated_energy | integer | Energy delegated to the address now. | |
next_billing_at | string (date-time) | null | ||
grace_until | string (date-time) | null | Set while a failed daily charge keeps the energy delegated (reported as suspended). | |
events | array of object (SubscriptionEvent) | GET /v1/subscriptions/{id} of a plan subscription only: the last 20 events, newest first. | |
events[].id | string | yes | |
events[].kind | enum: refill, charge, pause, resume, cancel, top_up_failed | yes | |
events[].energy_delta | integer | null | ||
events[].amount_sun | integer | null | ||
events[].txid | string | null | ||
events[].ts | string (date-time) | yes |
Cancel a subscription
DELETE /v1/subscriptions/{subscriptionId} · cancelSubscription
Auth: API key (HMAC).
Stops future refills. Rentals already delivered keep running until they expire; they are
not reclaimed and not refunded. The subscription stays readable with status: "cancelled".
Scope subscriptions.write, or a dashboard session with member role editor and
X-CSRF-Token.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
subscriptionId | path | string | yes |
Responses
| Status | Meaning |
|---|---|
204 | Cancelled. No body. |
401 | Missing, malformed or rejected credentials. |
404 | No such object, or it belongs to another account. The two are not distinguished. |
500 | Something broke on our side. |