Webhooks for TRON Energy Rental: How Not to Miss the Delivery Confirmation
Oliver BentleyTRON Research EditorShort answer: reliable delivery confirmation for energy on TRON cannot be built on webhooks alone. The protocol has no push notifications about resource delegation — the network reports the outcome only through transaction status. The workable setup is this: a webhook from the energy provider acts as a fast trigger, while the source of truth remains an on-chain check of the txID.
What counts as delivery confirmation
Energy delegation is an ordinary transaction (DelegateResourceContract in Stake 2.0), and it has several different kinds of "success":
- Broadcast accepted. The fullnode verified the signature and resources and placed the transaction in the mempool. This is not delivery yet.
- Receipt received. There is an execution result; in the documentation examples success is defined as
result == 'SUCCESS', while the other outcomes arefailedandunknown. - Block solidified. A transaction is final once at least 19 distinct active SRs have a
latestBlockNumno lower than the number of its block. This usually takes about a minute; until then the transaction is pending and could theoretically be discarded in a fork — that is how the transaction lifecycle is described.
A critical nuance: unknown is not a rejection. If confirmation is temporarily unavailable, you must not treat it as an execution error — the status has to be re-queried. This is exactly the mistake that most often derails deliveries under load: the service gets a timeout, marks the order unsuccessful and orders energy again.
Layer 1. The provider's webhook as a trigger
If the energy rental API can call your callback URL, treat the call as a "hint that it's time to check", not as proof of delivery. At a minimum, the payload should contain the order identifier and the txID; the energy amount, the recipient address and the duration you verify yourself.
The endpoint requirements are standard: HTTPS, a 2xx response immediately after the event is written to a queue (processing happens asynchronously), request signature verification, an IP allowlist, deduplication by event identifier. A webhook may arrive twice, arrive late, or never arrive at all — the handler must be ready for all three cases.
Layer 2. The poller as the source of truth
For every order, store the txID before broadcast and maintain your own state machine: created → broadcast → pending → confirmed / failed. A poller with exponential backoff pushes the status through to solidification and closes the order even if the webhook was lost.
Check the actual presence of the delegation with the right method: for Stake 2.0 that is GetDelegatedResourceV2, whereas GetDelegatedResource returns Stake 1.0 delegations — pick the wrong one and you get an empty response and conclude there is no energy. The second common false alert: the expire_time_for_energy and expire_time_for_bandwidth fields are zero and are not shown in the response if the delegation was made without a lock. A missing field here is normal.
Layer 3. Events instead of polling everything
If you need not just delegations but also contract events (for example, USDT TRC-20 deposits to hot addresses), rely on the event queries of TronGrid V1 and indexed events rather than reading through every record in sequence. The pattern is the same: the external layer speeds up reaction, while finality is determined by block solidification.
Retries without double payment
Idempotency rests on two keys: order_id (generated before the delivery request) and the txID (stored immediately after broadcast).
- one
order_id— no more than one paid delivery; a repeated POST with the same key returns the existing order; - a new request is allowed only from the terminal
failedstate, never frompending— including when polling returnedunknown; - an HTTP request timeout does not change the order state — only a txID check does;
- for a pool of addresses, create a separate order for each recipient address so that a partial failure does not re-issue the entire batch.
Keys and limits
Node access is configured through your choice of endpoint and an API key, which also governs quotas and rate limits; TronGrid offers key security settings — allowlists by User-Agent, Origin, contract address and API methods, as well as JWT. Separate keys by layer: one for the poller, one for production delivery, one for analytics — otherwise an exhausted reporting quota will halt your confirmations.
And remember: a successful delegation does not guarantee that your transaction will execute. For contract calls, the amount of TRX burned for energy is capped by fee_limit (set in sun, currently a maximum of 15,000 TRX); energy is charged per operation and is not refunded if the limit is exceeded. Estimate your needs with EstimateEnergy before sending.
Checklist
| Step | What the system must have |
|---|---|
| Order | order_id before the request, idempotent POST |
| Broadcast | txID stored before responding to the client |
| Webhook | HTTPS, signature, immediate 2xx, deduplication |
| Confirmation | receipt SUCCESS + block solidification |
| Verification | GetDelegatedResourceV2, address and amount |
| Fallback | poller with backoff, unknown ≠ failed |
Conclusion
Webhooks in TRON energy rental solve the problem of speed, not of certainty. Certainty comes only from the chain: txID → receipt → block solidification, plus verification of the delegation via the Stake 2.0 method. Build both layers and tie them to idempotency keys — then a lost or duplicated webhook stops being an incident.