Errors
The error format and every error code the API returns, with what to do.
Error format
{
"ok": false,
"error": "TX_EXPIRED",
"message": "Transaction expired",
"hint": "Call POST /construct-tx to build a fresh transaction."
}| Field | Meaning |
|---|---|
ok | Always false on errors. |
error | A code such as INSUFFICIENT_BALANCE. A few older endpoints put a short sentence here instead; those are listed below with their sentence. Match on this. |
message | Human-readable detail. Optional. |
hint | What to do next. Optional. |
details | Field-level problems on validation errors. |
code | Set on some 403 and 422 answers, for example SESSION_REQUIRED. |
A validation error looks like this:
{
"ok": false,
"error": "Validation failed",
"details": { "formErrors": [], "fieldErrors": { "idempotencyKey": ["Invalid uuid"] } }
}There are two kinds of errors:
- Request errors come back right away. Nothing was charged or broadcast.
- Operation errors happen later, while an accepted relay runs. The operation ends
failedwith anerrorCode. See Operation errors.
For retry patterns, see the Errors guide.
Auth and access
| Status | error / code | What to do |
|---|---|---|
| 401 | Authentication required | Send a valid key in x-api-key or Authorization: ApiKey. Missing, wrong, expired and revoked keys all land here. |
| 403 | Insufficient permissions | Your user's role lacks the permission for this endpoint. |
| 403 | code: "SESSION_REQUIRED" | This action needs a signed-in dashboard session. Do it in the dashboard. |
| 404 | Operation not found, Batch not found, Account not found, Key not found, Not found | Unknown ID or not yours. Not found usually means the ID is not a UUID. |
Validation
| Status | error | What to do |
|---|---|---|
| 422 | Validation failed (batch: VALIDATION_FAILED) | Fix the body. Read details.fieldErrors. |
| 422 | Invalid query parameters | Fix the query string. |
| 400 | Invalid JSON body | Construct transaction and create API key only. Other endpoints read broken JSON as {} and answer 422. |
| 422 | INVALID_PAYLOAD | payload is empty or a field is wrong. message names it. |
| 422 | UNSUPPORTED_FIELD | Remove adjustmentPolicy and send the exact energy_amount. |
| 422 | ENERGY_AMOUNT_BELOW_MINIMUM | Retry delegate_energy with details.suggestedEnergyAmount. |
Pricing
Only the public Pricing endpoints return these.
| Status | error | What to do |
|---|---|---|
| 503 | PRICE_UNAVAILABLE | No energy provider can be priced right now. Try again in a minute. |
| 502 | PRICE_QUOTE_FAILED | The current price could not be calculated. Try again. |
| 400 | Invalid query | Price history only. Fix hours or energy. |
| 502 | Failed to load price history | Price history only. Try again. |
| 422 | Invalid query parameters | Rate only. Fix energy: a whole number from 10,000 to 10,000,000. |
| 404 | Not found | Rate only. The org slug does not exist. |
| 400 | org is required | Price history only. Send org. |
| 404 | Organization not found | Price history only. The org slug does not exist. |
Signed transactions
| Status | error | What to do |
|---|---|---|
| 400 | TX_MALFORMED | Include the full signed TronWeb transaction object. |
| 400 | TX_NOT_SIGNED | Sign it in the wallet first. |
| 400 | TX_EXPIRED | Expired or too close to expiry. Build a new one and sign again. |
| 400 | TX_EXPIRING_SOON | Expires before this relay can finish (the message gives the seconds needed). Sign again with a longer expiration, or use construct-tx. |
| 400 | INSUFFICIENT_SENDER_BALANCE | The sender does not hold the TRX the transaction sends. Fund it, then sign again. |
| 400 | TX_DECODE_FAILED | Sign again. Do not change the object after signing: raw_data_hex must be present, txID must be its hash, and raw_data must match it. |
| 400 | TX_SENDER_MISMATCH | Sender differs from userAddress, or fee and user transactions have different senders. Sign both with one wallet. |
| 400 | FEE_RECIPIENT_MISMATCH | The fee transaction pays the wrong address. Use feeRecipient from the estimate. |
| 400 | TX_MISMATCH | Swap: sign every transaction from construct-tx, in order. |
| 422 | SIGNATURE_MISMATCH | Sign with the wallet that owns the sender address. |
| 422 | SIMULATION_REVERTED | execute only. The node shows the transaction would revert (for example, the sender lacks the tokens). Nothing was held or charged. Fix the cause, sign again. estimate never returns this; it sets simulation.reverted instead. |
Balance and availability
| Status | error | What to do |
|---|---|---|
| 422 | INSUFFICIENT_BALANCE | Top up your balance, then retry. See Billing. |
| 503 | RELAYER_UNDERFUNDED | Temporary platform problem. Retry later with the same idempotency key. |
| 422 | NO_PROVIDER, PROVIDER_NOT_FOUND, PROVIDER_NOT_CONFIGURED | No quote is available right now, or chain / mode is unknown. Retry later or lower the energy amount. |
| 422 | NO_SANDBOX_PROVIDER | Sandbox cannot quote this request. Try live or contact support. |
| 503 | TRON_BALANCE_CHECK_UNAVAILABLE, SUNSWAP_RPC_RATE_LIMITED, SUNSWAP_BALANCE_CHECK_UNAVAILABLE | The TRON network is busy. Retry in a few seconds. |
| 502 | ESTIMATION_FAILED, CONSTRUCT_FAILED, RELAY_FAILED or any other code | Upstream failure. Retry shortly. |
| 502 | no error; body has operationId and "status": "failed" | Execute: the relay could not start and was not broadcast. Retry with a new idempotency key. |
| 503 | retrySafe: false | Database outage, outcome unknown. Check the current state, or retry with the same idempotency key. |
| 500 | Operation failed | Unexpected error. Retry with the same idempotency key. |
Idempotency
| Status | error | What to do |
|---|---|---|
| 409 | IDEMPOTENCY_KEY_CONFLICT | The key is used by another user of your organization. Use a new UUID. |
| 409 | IDEMPOTENCY_KEY_REUSED | Batch key reused with different items. Use a new batchIdempotencyKey. |
Rate limits
| Status | error | What to do |
|---|---|---|
| 429 | Rate limit exceeded. Maximum 100 execute requests per minute. | Wait Retry-After seconds. |
| 429 | Rate limit exceeded. Maximum 30 estimate requests per minute. | Wait Retry-After seconds. |
| 429 | Rate limit exceeded. Maximum 30 construct-tx requests per minute. | Wait Retry-After seconds. |
| 429 | RATE_LIMITED | Batch: too many calls or not enough execute points. Wait up to a minute. |
| 429 | Rate limit exceeded. Maximum 25 withdrawal requests per hour. | Wait before withdrawing again. |
Construct transaction
| Status | error | What to do |
|---|---|---|
| 422 | Fee payment is not available right now. Please contact support. | Token fee modes are not set up for your account. Contact support. |
| 422 | Missing fee token contract | Send feeTokenContract for token_pay. |
| 422 | Missing fee amount, Missing or invalid native TRX fee amount | Send feeAmountSun as a positive whole number. |
| 422 | Invalid callValue: must be a whole number of sun within range | Fix callValue. |
| 500 | Failed to construct transaction, Failed to construct fee transaction, Failed to construct user transaction | Check the contract, selector and parameters, then retry. |
Operations and batches
| Status | error | What to do |
|---|---|---|
| 409 | Operation is already <status> and can no longer be cancelled., Operation is no longer in a cancellable state | Cancel works only while pending or reserved. Read the operation to see where it is. |
| 502 | Failed to fetch operation statistics | Retry shortly. |
| 413 | BODY_TOO_LARGE | Keep the batch body under 8 MB. |
| 422 | BATCH_TOO_LARGE | Split into smaller batches (25 items by default). |
| 422 | UNSUPPORTED_MODE | sunswap_swap cannot be batched. |
| 409 | BATCH_NOT_RETRYABLE | Wait until the batch finishes dispatching. |
| 409 | NO_RETRYABLE_ITEMS | Nothing to retry. |
| 409 | RETRY_BUDGET_EXHAUSTED | Items were retried 3 times. Submit them in a new batch. |
Balance, keys and node links
| Status | error / code | What to do |
|---|---|---|
| 404 | No deposit address found for this chain and environment | Create one with GET /api/payment_gateways/portal/deposit. |
| 422 | Deposits are not available for this network right now. | Contact support. |
| 500 | Failed to resolve deposit address | Retry shortly. |
| 422 | Invalid payload | Alerts PUT: fix the body. |
| 502 | Failed to fetch alert config, Failed to update alert config | Retry shortly. |
| 422 | Insufficient balance for withdrawal | Withdraw less. |
| 422 | Minimum withdrawal amount is 1000000 | Withdraw at least 1 TRX (1000000 sun). |
| 422 | Maximum single withdrawal exceeded | Withdraw at most 100,000 TRX per request. Split larger amounts. |
| 422 | Invalid TRON destination address | The address checksum is wrong. Copy the address again. |
| 409 | This withdrawal was previously cancelled. Use a new idempotencyKey to retry. | Use a new idempotencyKey. |
| 409 | This idempotencyKey was already used for a different withdrawal. Use a new idempotencyKey. | The key was used with another amount, address or user. Use a new idempotencyKey. |
| 422 | limit_reached | You have 25 usable API keys. Revoke one first. |
| 404 | Missing or invalid id parameter | Send ?id= with the key's UUID. |
| 422 | code: "LINK_LIMIT_REACHED" | You have 50 active node links. Revoke one first. |
Swap
| Status | error | What to do |
|---|---|---|
| 422 | SYNC_UNSUPPORTED | Do not send sync: true for sunswap_swap. |
| 409 | DRAFT_EXPIRED, DRAFT_STALE | Build the step again with construct-tx, sign and execute. DRAFT_STALE can also mean the draft was priced for another account, or before a platform update. |
| 409 | SUNSWAP_OPERATION_IN_PROGRESS | A step is still running. Wait for it. |
| 409 | SUNSWAP_SESSION_COMPLETED | This session's swap is done. Estimate again without session_id to start another. |
| 409 | SUNSWAP_SESSION_REPRICE_REQUIRED | The session's price is out of date for your account. Call estimate again with the same session_id, then construct-tx. |
| 503 | SUNSWAP_RPC_RATE_LIMITED, SUNSWAP_BALANCE_CHECK_UNAVAILABLE | The network is busy. Retry shortly. |
| 502 | SUNSWAP_UNSIGNED_TX_INVALID | The step could not be built. Retry construct-tx. |
| 422 | SUNSWAP_INVALID_INTENT, SUNSWAP_RECIPIENT_MISMATCH and the other SUNSWAP_* codes | The swap cannot go ahead as asked. Read message. See Swap. |
Operation errors
These appear in errorCode on a failed operation. The list is not complete: treat unknown codes as a generic failure and show errorMessage.
errorCode | Meaning |
|---|---|
INSUFFICIENT_BALANCE, BUDGET_CAP_EXCEEDED | Your balance or monthly budget cap could not cover the relay. |
RESERVE_FAILED | The cost could not be held on your balance. |
ESTIMATION_FAILED | Re-quoting failed while running. |
PROVIDER_NOT_FOUND | No quote was available when the relay ran. |
RELAY_STEP_FAILED, RELAY_FAILED | A step failed and no more specific reason is known. |
WORKFLOW_START_FAILED | The relay could not start. |
STUCK_OPERATION | The relay stopped making progress and was closed. |
WORKFLOW_EXHAUSTED | Retries ran out. |
UNKNOWN_ERROR | Unexpected failure. |
Before you resubmit a failed relay, check txHash on the chain. If your user's transaction landed, do not send it again. A resubmit needs a new idempotency key.