{
  "openapi": "3.0.3",
  "info": {
    "title": "gasrent API",
    "version": "1.0.0",
    "description": "HTTP API for a Tron energy and bandwidth rental. Quote a price, place an order, activate an address, estimate energy for a USDT transfer, top up TRX or USDT, withdraw, exchange TRX and USDT, and receive webhooks.\n\nThe canonical document is https://gasrent.click/openapi.json. Downloading it does not require a key. Human-readable reference: https://gasrent.click/api.html.\n\nAuthenticate with the X-API-KEY header. A key is issued only in the cabinet and the full key is shown once, when it is issued. Examples use the placeholder YOUR_API_KEY. GET /api/v1/health does not use a key. A key sent with that call is ignored.\n\nA new key has full access. A read-only key can call GET. Any other method returns 403 key_read_only. A read-only key does not receive the webhook secret.\n\nEnergy duration is one of 15m, 1h, 1d, 3d. There is no 7-day energy rental. Bandwidth duration is one of 5m, 1h, 1d, 3d, 7d. There is no 15-minute bandwidth rental. Bandwidth uses the same key and the same TRX balance as energy. Its orders are separate: an energy id is not a bandwidth id.\n\nRequest and response bodies are JSON. Integers and booleans in a body are JSON numbers and booleans. A stringified number is rejected.\n\nPOST /api/v1/order, POST /api/v1/bandwidth, POST /api/v1/activation, POST /api/v1/topup, POST /api/v1/withdraw, and POST /api/v1/exchange with preview false accept an idempotency key. Send it in the JSON field idempotency_key or in the X-Idempotency-Key header. If both are set, they must be equal. The key is 8 to 128 characters. The same key and the same body return the original result, once that call has finished. The same key and a different body return 409 conflict. An energy key and a bandwidth key do not see each other.\n\nThe IP whitelist is set in the cabinet. With no addresses on the list, a key works from anywhere. After the first address, a call from any other address is rejected with 403 ip_not_allowed.\n\nLimits: 100 requests in the current UTC minute and 5000 requests in the current UTC hour, per account. GET /api/v1/health is not counted. Over the limit the response is 429 rate_limited.\n\nA failed call returns an error_code and an HTTP status other than 200.\n\nThis document lists the customer API published on the API reference. It does not include cabinet session methods such as sign-in, API key management, IP list changes, or pool wallets.",
    "contact": {
      "email": "top@gasrent.click",
      "url": "https://gasrent.click/api.html"
    }
  },
  "externalDocs": {
    "description": "API reference",
    "url": "https://gasrent.click/api.html"
  },
  "servers": [
    {
      "url": "https://gasrent.click",
      "description": "Production"
    },
    {
      "url": "https://test.gasrent.click",
      "description": "Test"
    }
  ],
  "tags": [
    {
      "name": "Service",
      "description": "Liveness. No API key."
    },
    {
      "name": "Account",
      "description": "Balance and ledger."
    },
    {
      "name": "Energy",
      "description": "Energy quotes and orders. Duration is 15m, 1h, 1d, or 3d."
    },
    {
      "name": "Bandwidth",
      "description": "Bandwidth quotes and orders. Duration is 5m, 1h, 1d, 3d, or 7d."
    },
    {
      "name": "Activation",
      "description": "Activate a Tron address."
    },
    {
      "name": "Estimate",
      "description": "Energy and bandwidth a USDT transfer would use. Does not buy anything."
    },
    {
      "name": "Top-up",
      "description": "Add TRX or USDT to the balance."
    },
    {
      "name": "Webhook",
      "description": "Callback URL and secret. gasrent POSTs events to that URL."
    },
    {
      "name": "Exchange",
      "description": "Swap TRX and USDT."
    },
    {
      "name": "Withdrawal",
      "description": "Pay out TRX or USDT to an address on the account list."
    }
  ],
  "security": [
    {
      "ApiKey": []
    }
  ],
  "paths": {
    "/api/v1/health": {
      "get": {
        "tags": [
          "Service"
        ],
        "operationId": "getHealth",
        "summary": "Check that the API can take calls",
        "description": "No key. A key sent with this call is ignored, so a wrong or expired key still returns 200 while the service is up. To check a key, call another method, such as GET /api/v1/balance. This call is not counted in the rate limit.",
        "security": [],
        "responses": {
          "200": {
            "description": "The service is ready.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Health.",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "True when the service is ready to take calls.",
                      "example": true
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/balance": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getBalance",
        "summary": "Spendable TRX and USDT balances",
        "description": "Returns the spendable balances. Energy, bandwidth, and activation use TRX. A top-up can add TRX or USDT.",
        "responses": {
          "200": {
            "description": "Balances for the key's account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Balance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/quote": {
      "post": {
        "tags": [
          "Energy"
        ],
        "operationId": "quoteEnergy",
        "summary": "Price an energy rental",
        "description": "Returns a price. Does not charge the balance and does not delegate energy. address is optional. When it is present and that account is not activated yet, price_trx includes the activation fee and activation is true. The activation check uses the stored result for an address already seen as active. A larger amount or a longer duration is skipped when its energy price, before activation, is above the TRX the network would burn for the requested energy.",
        "requestBody": {
          "required": true,
          "description": "Energy quote.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Energy quote request. volume is an integer from 65000 to 4000000 inclusive. duration is 15m, 1h, 1d, or 3d.",
                "properties": {
                  "volume": {
                    "type": "integer",
                    "description": "Required. Inclusive range 65000 to 4000000.",
                    "example": 65000,
                    "minimum": 65000,
                    "maximum": 4000000
                  },
                  "duration": {
                    "$ref": "#/components/schemas/EnergyDuration"
                  },
                  "exact_volume": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. When true, a supplier that does not sell the requested amount is excluded. When false, the response volume may be larger than the request when that fill costs less. It is never smaller.",
                    "example": false
                  },
                  "exact_duration": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. When false, a longer duration is eligible and a shorter one is not.",
                    "example": false
                  },
                  "no_activation": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. When true, an address that is not activated returns 400 inactive_address instead of a price that includes activation.",
                    "example": false
                  },
                  "address": {
                    "type": "string",
                    "description": "Optional. Tron address that would receive the energy.",
                    "example": "YOUR_TRON_ADDRESS"
                  }
                },
                "required": [
                  "volume",
                  "duration"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Price that a later order would pay. volume and duration may be larger than the request when the exact flags are false.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Energy quote.",
                  "properties": {
                    "volume": {
                      "type": "integer",
                      "description": "The amount that would be delegated.",
                      "example": 65000
                    },
                    "duration": {
                      "$ref": "#/components/schemas/EnergyDuration"
                    },
                    "price_trx": {
                      "type": "string",
                      "description": "Order total in TRX. Includes activation when activation is true. Six digits after the point.",
                      "example": "1.911000"
                    },
                    "price_sun": {
                      "type": "string",
                      "description": "Sun for one energy. A fraction is kept, so price_sun x volume / 1000000 equals price_trx. When activation is included, the rate is taken from that combined total.",
                      "example": "29.4"
                    },
                    "activation": {
                      "type": "boolean",
                      "description": "True when the address was sent and is not activated, so the price includes activation. False when the address is omitted or already active.",
                      "example": false
                    }
                  },
                  "required": [
                    "volume",
                    "duration",
                    "price_trx",
                    "price_sun",
                    "activation"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/order": {
      "post": {
        "tags": [
          "Energy"
        ],
        "operationId": "createEnergyOrder",
        "summary": "Buy energy",
        "description": "Buys energy and charges the balance. The request does not include a price. The service tries the lowest offer first. price_trx is the full charge: the energy that was accepted, plus activation when this order activated the address. If the address is not activated, gasrent activates it first, charges the activation fee, waits until the account is visible on the network, and only then delegates energy. The activation fee is a separate balance row. With no_activation true, an inactive address returns 400 inactive_address and the balance is not charged. A call that cannot buy does not return an order id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Energy order.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Energy order. volume is an integer from 65000 to 4000000. duration is 15m, 1h, 1d, or 3d.",
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "Required. Tron address that receives the energy.",
                    "example": "YOUR_TRON_ADDRESS"
                  },
                  "volume": {
                    "type": "integer",
                    "description": "Required. Inclusive range 65000 to 4000000.",
                    "example": 65000,
                    "minimum": 65000,
                    "maximum": 4000000
                  },
                  "duration": {
                    "$ref": "#/components/schemas/EnergyDuration"
                  },
                  "exact_volume": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. When true, a supplier that does not sell the requested amount is excluded. When false, the response volume may be larger than the request when that fill costs less. It is never smaller.",
                    "example": false
                  },
                  "exact_duration": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. When false, a longer duration is eligible and a shorter one is not.",
                    "example": false
                  },
                  "no_activation": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. When true, an address that is not activated returns 400 inactive_address instead of a price that includes activation.",
                    "example": false
                  },
                  "idempotency_key": {
                    "type": "string",
                    "description": "Optional. 8 to 128 characters. See the idempotency rules. Recommended. A dropped connection can be repeated safely only when the key is reused with the same body.",
                    "example": "order-20261023-0001",
                    "minLength": 8,
                    "maxLength": 128
                  }
                },
                "required": [
                  "address",
                  "volume",
                  "duration"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The order. status starts as Pending. Repeat GET /api/v1/order/{order_id} until it leaves Pending. Filled means the delegation is in place. Cancelled means the energy charge was returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnergyOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "get": {
        "tags": [
          "Energy"
        ],
        "operationId": "listEnergyOrders",
        "summary": "List energy orders",
        "description": "Returns up to 50 orders for the account, newest first. Leave a filter out to skip it. A Cancelled order is included. A purchase that failed before an order id was issued is not included. Add format=csv, format=xlsx, or format=txt to download every matching row, at most 100000 rows, instead of one JSON page. Times in the file are UTC.",
        "parameters": [
          {
            "name": "before_id",
            "in": "query",
            "required": false,
            "description": "Optional. order_id of the last element on this page. The response is the next older page. It must be a UUID. Ignored when format is set.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "a3f2c8e1-7b44-4d19-9c0e-6f1a2b3c4d5e"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Optional. A calendar day YYYY-MM-DD is the start of that UTC day. An instant YYYY-MM-DDTHH:MM:SSZ is inclusive. Leave from and to out for the whole history.",
            "schema": {
              "type": "string"
            },
            "example": "2026-11-01T00:00:00Z"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Optional. A calendar day YYYY-MM-DD includes that whole UTC day. An instant YYYY-MM-DDTHH:MM:SSZ is exclusive.",
            "schema": {
              "type": "string"
            },
            "example": "2026-12-01T00:00:00Z"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Optional. Pending, Filled, or Cancelled.",
            "schema": {
              "$ref": "#/components/schemas/OrderStatus"
            },
            "example": "Filled"
          },
          {
            "name": "duration",
            "in": "query",
            "required": false,
            "description": "Optional. Duration on the order.",
            "schema": {
              "$ref": "#/components/schemas/EnergyDuration"
            }
          },
          {
            "name": "address",
            "in": "query",
            "required": false,
            "description": "Optional. The whole receiver address, or at least 4 characters from its start.",
            "schema": {
              "type": "string"
            },
            "example": "T9yD"
          },
          {
            "name": "uuid",
            "in": "query",
            "required": false,
            "description": "Optional. The whole order_id, or at least 4 characters from its start.",
            "schema": {
              "type": "string"
            },
            "example": "a3f2c8e1"
          },
          {
            "name": "volume_min",
            "in": "query",
            "required": false,
            "description": "Optional. Smallest energy on the order, inclusive.",
            "schema": {
              "type": "string"
            },
            "example": "65000"
          },
          {
            "name": "volume_max",
            "in": "query",
            "required": false,
            "description": "Optional. Largest energy on the order, inclusive.",
            "schema": {
              "type": "string"
            },
            "example": "100000"
          },
          {
            "name": "price_min",
            "in": "query",
            "required": false,
            "description": "Optional. Smallest price in TRX, inclusive. The price includes account activation when that order charged it.",
            "schema": {
              "type": "string"
            },
            "example": "1"
          },
          {
            "name": "price_max",
            "in": "query",
            "required": false,
            "description": "Optional. Largest price in TRX, inclusive. The price includes account activation when that order charged it.",
            "schema": {
              "type": "string"
            },
            "example": "10"
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Optional. csv, xlsx, or txt. Downloads every order that matches the other filters. before_id is ignored.",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx",
                "txt"
              ]
            },
            "example": "csv"
          }
        ],
        "responses": {
          "200": {
            "description": "A JSON array. Each element is an energy order. With format set, the body is a file instead.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "maxItems": 50,
                  "items": {
                    "$ref": "#/components/schemas/EnergyOrder"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/order/{order_id}": {
      "get": {
        "tags": [
          "Energy"
        ],
        "operationId": "getEnergyOrder",
        "summary": "Read one energy order",
        "description": "Returns one order of this account, including an order whose status is Cancelled. While status is Pending, repeat this request. An id this account was never given is 404 not_found.",
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "description": "Energy order UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "a3f2c8e1-7b44-4d19-9c0e-6f1a2b3c4d5e"
          }
        ],
        "responses": {
          "200": {
            "description": "The order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnergyOrder"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/bandwidth/quote": {
      "post": {
        "tags": [
          "Bandwidth"
        ],
        "operationId": "quoteBandwidth",
        "summary": "Price a bandwidth rental",
        "description": "Returns a bandwidth price. Does not charge the balance and does not delegate bandwidth. address is optional and is not activated. The price never includes an activation fee. There is no no_activation field. With exact_volume false, the response volume may be larger than the request when that fill costs less. It is never smaller. A longer duration is eligible when exact_duration is false. A shorter one is not. Burn is the cost of those points once. It is not multiplied by the rental duration.",
        "requestBody": {
          "required": true,
          "description": "Bandwidth quote.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Bandwidth quote. volume is an integer from 1 to 100000. duration is 5m, 1h, 1d, 3d, or 7d.",
                "properties": {
                  "volume": {
                    "type": "integer",
                    "description": "Required. Inclusive range 1 to 100000. A supplier may still refuse a size below its own minimum.",
                    "example": 1000,
                    "minimum": 1,
                    "maximum": 100000
                  },
                  "duration": {
                    "$ref": "#/components/schemas/BandwidthDuration"
                  },
                  "exact_volume": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. When true, a supplier that does not sell this amount is excluded.",
                    "example": false
                  },
                  "exact_duration": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. When true, only this duration is eligible. A shorter duration is never used.",
                    "example": false
                  },
                  "address": {
                    "type": "string",
                    "description": "Optional. Tron address that would receive the bandwidth. It is checked when present. It does not change the price.",
                    "example": "YOUR_TRON_ADDRESS"
                  }
                },
                "required": [
                  "volume",
                  "duration"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Price a later bandwidth order would pay.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Bandwidth quote.",
                  "properties": {
                    "resource": {
                      "type": "string",
                      "description": "Always bandwidth.",
                      "example": "bandwidth",
                      "enum": [
                        "bandwidth"
                      ]
                    },
                    "volume": {
                      "type": "integer",
                      "description": "The amount that would be delegated. It may be larger than the request when exact_volume is false.",
                      "example": 1000
                    },
                    "duration": {
                      "$ref": "#/components/schemas/BandwidthDuration"
                    },
                    "price_trx": {
                      "type": "string",
                      "description": "Price in TRX. Activation is not included. Six digits after the point.",
                      "example": "0.801800"
                    },
                    "price_sun": {
                      "type": "string",
                      "description": "Sun for one bandwidth point. A fraction is kept, so price_sun x volume / 1000000 equals price_trx.",
                      "example": "801.8"
                    }
                  },
                  "required": [
                    "resource",
                    "volume",
                    "duration",
                    "price_trx",
                    "price_sun"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/bandwidth": {
      "post": {
        "tags": [
          "Bandwidth"
        ],
        "operationId": "createBandwidthOrder",
        "summary": "Buy bandwidth",
        "description": "Buys bandwidth and charges the balance. The request does not include a price. The service tries the lowest offer first. The address is not activated. If no supplier accepts it, the call returns 503 unavailable and the balance is not charged. Pending means the charge is held and the chain has not confirmed the delegation yet. Filled means the chain shows a bandwidth delegation to this address for at least 98% of volume. Cancelled means the charge was returned. A call that cannot buy does not return an order id. A bandwidth idempotency key is not an energy key.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Bandwidth order.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Bandwidth order. volume is an integer from 1 to 100000. duration is 5m, 1h, 1d, 3d, or 7d.",
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "Required. Tron address that receives the bandwidth. This call does not activate it.",
                    "example": "YOUR_TRON_ADDRESS"
                  },
                  "volume": {
                    "type": "integer",
                    "description": "Required. Inclusive range 1 to 100000.",
                    "example": 1000,
                    "minimum": 1,
                    "maximum": 100000
                  },
                  "duration": {
                    "$ref": "#/components/schemas/BandwidthDuration"
                  },
                  "exact_volume": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. Same rule as the bandwidth quote.",
                    "example": false
                  },
                  "exact_duration": {
                    "type": "boolean",
                    "description": "Optional. Omitted means false. Same rule as the bandwidth quote.",
                    "example": false
                  },
                  "idempotency_key": {
                    "type": "string",
                    "description": "Optional. 8 to 128 characters. See the idempotency rules. Recommended. A dropped connection can be repeated safely only when the key is reused with the same body.",
                    "example": "bandwidth-20261025-0001",
                    "minLength": 8,
                    "maxLength": 128
                  }
                },
                "required": [
                  "address",
                  "volume",
                  "duration"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The bandwidth order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BandwidthOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "get": {
        "tags": [
          "Bandwidth"
        ],
        "operationId": "listBandwidthOrders",
        "summary": "List bandwidth orders",
        "description": "Returns this account's bandwidth orders, newest first, up to 50. Energy orders are not included. Add format=csv, format=xlsx, or format=txt to download every matching row, at most 100000 rows, instead of one JSON page. Times in the file are UTC.",
        "parameters": [
          {
            "name": "before_id",
            "in": "query",
            "required": false,
            "description": "Optional. A bandwidth order UUID from this account. A value that is not a UUID, or an id this account was never given, is 400 bad_request. Ignored when format is set.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "d5e6f708-1920-4a1b-8c2d-3e4f5a6b7c8d"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Optional. A calendar day YYYY-MM-DD is the start of that UTC day. An instant YYYY-MM-DDTHH:MM:SSZ is inclusive.",
            "schema": {
              "type": "string"
            },
            "example": "2026-11-01T00:00:00Z"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Optional. A calendar day YYYY-MM-DD includes that whole UTC day. An instant YYYY-MM-DDTHH:MM:SSZ is exclusive.",
            "schema": {
              "type": "string"
            },
            "example": "2026-12-01T00:00:00Z"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Optional. Pending, Filled, or Cancelled.",
            "schema": {
              "$ref": "#/components/schemas/OrderStatus"
            },
            "example": "Filled"
          },
          {
            "name": "duration",
            "in": "query",
            "required": false,
            "description": "Optional. Duration on the order: 5m, 1h, 1d, 3d, or 7d.",
            "schema": {
              "$ref": "#/components/schemas/BandwidthDuration"
            }
          },
          {
            "name": "address",
            "in": "query",
            "required": false,
            "description": "Optional. The whole receiver address, or at least 4 characters from its start.",
            "schema": {
              "type": "string"
            },
            "example": "T9yD"
          },
          {
            "name": "uuid",
            "in": "query",
            "required": false,
            "description": "Optional. The whole order_id, or at least 4 characters from its start.",
            "schema": {
              "type": "string"
            },
            "example": "d5e6f708"
          },
          {
            "name": "volume_min",
            "in": "query",
            "required": false,
            "description": "Optional. Smallest bandwidth on the order, inclusive.",
            "schema": {
              "type": "string"
            },
            "example": "1000"
          },
          {
            "name": "volume_max",
            "in": "query",
            "required": false,
            "description": "Optional. Largest bandwidth on the order, inclusive.",
            "schema": {
              "type": "string"
            },
            "example": "5000"
          },
          {
            "name": "price_min",
            "in": "query",
            "required": false,
            "description": "Optional. Smallest price in TRX, inclusive.",
            "schema": {
              "type": "string"
            },
            "example": "1"
          },
          {
            "name": "price_max",
            "in": "query",
            "required": false,
            "description": "Optional. Largest price in TRX, inclusive.",
            "schema": {
              "type": "string"
            },
            "example": "10"
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Optional. csv, xlsx, or txt. Downloads every bandwidth order that matches the other filters. before_id is ignored.",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx",
                "txt"
              ]
            },
            "example": "csv"
          }
        ],
        "responses": {
          "200": {
            "description": "A JSON array. Each element has the same fields as POST /api/v1/bandwidth.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "maxItems": 50,
                  "items": {
                    "$ref": "#/components/schemas/BandwidthOrder"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/bandwidth/{order_id}": {
      "get": {
        "tags": [
          "Bandwidth"
        ],
        "operationId": "getBandwidthOrder",
        "summary": "Read one bandwidth order",
        "description": "Returns one bandwidth order of this account, including Cancelled. While status is Pending, repeat this request. An energy order id, or an id this account was never given, is 404 not_found. The fields are the same as POST /api/v1/bandwidth.",
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "description": "Bandwidth order UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "d5e6f708-1920-4a1b-8c2d-3e4f5a6b7c8d"
          }
        ],
        "responses": {
          "200": {
            "description": "The bandwidth order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BandwidthOrder"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/transaction": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "listTransactions",
        "summary": "List balance movements",
        "description": "Returns one page of balance movements for the account. A row that does not change the balance is omitted. Leave a query parameter out to skip that filter. A bad value is 400 bad_request. Add format=csv, format=xlsx, or format=txt to download every matching row, at most 100000 rows, instead of one JSON page. Times in the file are UTC. page and limit are ignored for a file.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "Optional. deposit, debit, refund, adjustment, exchange, withdrawal, supply, reward, reward_out, or affiliate.",
            "schema": {
              "type": "string",
              "enum": [
                "deposit",
                "debit",
                "refund",
                "adjustment",
                "exchange",
                "withdrawal",
                "supply",
                "reward",
                "reward_out",
                "affiliate"
              ]
            },
            "example": "deposit"
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Optional. trx or usdt. Keeps rows in that currency.",
            "schema": {
              "$ref": "#/components/schemas/Currency"
            },
            "example": "trx"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Optional. Up to 128 characters. A UUID matches an energy order, a bandwidth order, an activation, a top-up, or the public id of a ledger row. Any text also matches a txid that contains it.",
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "example": "a3f2c8e1-7b44-4d19-9c0e-6f1a2b3c4d5e"
          },
          {
            "name": "uuid",
            "in": "query",
            "required": false,
            "description": "Optional. Up to 36 characters, hexadecimal digits and hyphens. Keeps rows whose energy order, bandwidth order, or activation UUID contains this text.",
            "schema": {
              "type": "string",
              "maxLength": 36
            },
            "example": "a3f2c8e1"
          },
          {
            "name": "subject",
            "in": "query",
            "required": false,
            "description": "Optional. energy or bandwidth. Keeps rows charged for that kind of order, including a refund of one.",
            "schema": {
              "type": "string",
              "enum": [
                "energy",
                "bandwidth"
              ]
            },
            "example": "energy"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Optional. A calendar day YYYY-MM-DD is the start of that UTC day. An instant YYYY-MM-DDTHH:MM:SSZ is inclusive.",
            "schema": {
              "type": "string"
            },
            "example": "2026-10-01"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Optional. A calendar day YYYY-MM-DD includes that whole UTC day. An instant YYYY-MM-DDTHH:MM:SSZ is exclusive.",
            "schema": {
              "type": "string"
            },
            "example": "2026-10-23"
          },
          {
            "name": "min",
            "in": "query",
            "required": false,
            "description": "Optional. Signed amount in the row currency, inclusive. A charge is negative, so min=0 leaves charges out.",
            "schema": {
              "type": "string"
            },
            "example": "0"
          },
          {
            "name": "max",
            "in": "query",
            "required": false,
            "description": "Optional. Signed amount in the row currency, inclusive.",
            "schema": {
              "type": "string"
            },
            "example": "100"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Optional. created (default) or amount. Equal values keep the same order by row id.",
            "schema": {
              "type": "string",
              "enum": [
                "created",
                "amount"
              ],
              "default": "created"
            },
            "example": "created"
          },
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "description": "Optional. desc (default) or asc.",
            "schema": {
              "type": "string",
              "enum": [
                "desc",
                "asc"
              ],
              "default": "desc"
            },
            "example": "desc"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Optional. Starts at 1. Ignored when format is set.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "example": 1
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Optional. Defaults to 50. The range is 1 to 100. Ignored when format is set.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "example": 50
          },
          {
            "name": "topup_id",
            "in": "query",
            "required": false,
            "description": "Optional. UUID of one top-up. Only rows for that top-up.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "b7e1d4a2-6c33-4a18-8b0d-5e2f1a0b9c8d"
          },
          {
            "name": "related_id",
            "in": "query",
            "required": false,
            "description": "Optional. Public id of a ledger row. Returns that row and the rows that point at it.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "e1f2a3b4-c5d6-4789-a012-3456789abcde"
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Optional. csv, xlsx, or txt. Downloads every row that matches the other filters, not one page. page and limit are ignored.",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx",
                "txt"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page. With format set, the body is a file instead of this JSON object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/activation/quote": {
      "post": {
        "tags": [
          "Activation"
        ],
        "operationId": "quoteActivation",
        "summary": "Price an activation",
        "description": "Returns the price to activate a Tron address. Does not charge the balance and does not activate the address. The price is the network account-creation fee, plus the bandwidth of the activation transaction at the network bandwidth price. If the address is already active, active is true and price_trx is 0.000000.",
        "requestBody": {
          "required": true,
          "description": "Activation quote.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Activation quote.",
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "Required. Tron address to price.",
                    "example": "YOUR_TRON_ADDRESS"
                  }
                },
                "required": [
                  "address"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Activation price.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Activation quote.",
                  "properties": {
                    "address": {
                      "type": "string",
                      "description": "The address from the request.",
                      "example": "YOUR_TRON_ADDRESS"
                    },
                    "active": {
                      "type": "boolean",
                      "description": "True when the address is already activated. Nothing is charged in that case.",
                      "example": false
                    },
                    "price_trx": {
                      "type": "string",
                      "description": "What an activation would charge. Six digits after the point.",
                      "example": "1.397000"
                    }
                  },
                  "required": [
                    "address",
                    "active",
                    "price_trx"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/activation": {
      "post": {
        "tags": [
          "Activation"
        ],
        "operationId": "createActivation",
        "summary": "Activate an address",
        "description": "Activates the address and charges price_trx. The request does not include a price. The charge is calculated when the call runs, so it can differ from an earlier quote. An address that is already active returns 400 already_active. A successful broadcast returns Pending until the network confirms it, then Filled. If the network rejects the transaction after it was broadcast, the status becomes Cancelled and the charge is returned. If the transaction is not broadcast, the response is 503 unavailable and no activation id is returned.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Activation.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Activation request.",
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "Required. Tron address to activate.",
                    "example": "YOUR_TRON_ADDRESS"
                  },
                  "idempotency_key": {
                    "type": "string",
                    "description": "Optional. 8 to 128 characters. See the idempotency rules. Recommended. A dropped connection can be repeated safely only when the key is reused with the same body.",
                    "example": "activation-20261023-0001",
                    "minLength": 8,
                    "maxLength": 128
                  }
                },
                "required": [
                  "address"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The activation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Activation"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/activation/{activation_id}": {
      "get": {
        "tags": [
          "Activation"
        ],
        "operationId": "getActivation",
        "summary": "Read one activation",
        "description": "Returns one activation. A Pending activation is checked against the network before the response. The body is the same as POST /api/v1/activation.",
        "parameters": [
          {
            "name": "activation_id",
            "in": "path",
            "required": true,
            "description": "Activation UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "c4d8e2f1-1a22-4b33-8c44-7d5e6f708192"
          }
        ],
        "responses": {
          "200": {
            "description": "The activation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Activation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/energy": {
      "post": {
        "tags": [
          "Estimate"
        ],
        "operationId": "estimateUsdtTransfer",
        "summary": "Estimate energy for a USDT transfer",
        "description": "Returns how much energy and bandwidth one USDT transfer from from_address to to_address would use, and how much of each the sender already has. Does not buy anything and does not return a price. Price an energy fill with POST /api/v1/quote. Price a bandwidth fill with POST /api/v1/bandwidth/quote. The simulated transfer is 0.000001 USDT. If the sender holds none, the response is 400 insufficient_usdt. If the sender holds some USDT but the transfer still reverts, the response is 400 transfer_reverted. Send to_address or to_addresses, not both. to_addresses holds 1 to 20 addresses. A longer list returns 400 too_many_addresses.",
        "requestBody": {
          "required": true,
          "description": "Energy estimate.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Send from_address and either to_address or to_addresses.",
                "properties": {
                  "from_address": {
                    "type": "string",
                    "description": "Required. Active Tron address that would send the USDT. It must hold at least 0.000001 USDT.",
                    "example": "YOUR_TRON_ADDRESS"
                  },
                  "to_address": {
                    "type": "string",
                    "description": "Tron address that would receive the USDT. Send this or to_addresses, not both.",
                    "example": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
                  },
                  "to_addresses": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "description": "A batch. From 1 to 20 Tron addresses. The same address may repeat, and each repeat is one more transfer.",
                    "items": {
                      "type": "string"
                    },
                    "example": [
                      "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
                    ]
                  }
                },
                "required": [
                  "from_address"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Energy and bandwidth the transfer would use.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnergyEstimate"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/topup": {
      "post": {
        "tags": [
          "Top-up"
        ],
        "operationId": "createTopup",
        "summary": "Open a top-up",
        "description": "Opens a top-up. Send one transfer of the returned amount_trx to the returned address before expires_at. trx is native TRX. usdt is TRC20 USDT on TRON. A different amount or the other currency is not matched to this top-up. An account may have at most 5 unfinished top-ups (pending, cooling, or seen). Above that, the response is 429 too_many_topups. A different amount_trx or currency with the same idempotency key returns 409 conflict.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Top-up. amount_trx is a JSON integer of at least 1, not a string.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Top-up request. The field name stays amount_trx for both TRX and USDT.",
                "properties": {
                  "amount_trx": {
                    "type": "integer",
                    "description": "Required. Whole units of currency, minimum 1.",
                    "example": 25,
                    "minimum": 1
                  },
                  "currency": {
                    "type": "string",
                    "description": "Optional. trx or usdt. Omitted means trx.",
                    "example": "trx",
                    "enum": [
                      "trx",
                      "usdt"
                    ],
                    "default": "trx"
                  },
                  "idempotency_key": {
                    "type": "string",
                    "description": "Optional. 8 to 128 characters. See the idempotency rules. Recommended. A dropped connection can be repeated safely only when the key is reused with the same body.",
                    "example": "topup-20261023-0001",
                    "minLength": 8,
                    "maxLength": 128
                  }
                },
                "required": [
                  "amount_trx"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The new top-up. Send amount_trx of currency to address before expires_at.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Opened top-up. status is not included on create. Read it with GET /api/v1/topup/{topup_id}.",
                  "properties": {
                    "topup_id": {
                      "type": "string",
                      "description": "UUID of the top-up.",
                      "example": "b7e1d4a2-6c33-4a18-8b0d-5e2f1a0b9c8d",
                      "format": "uuid"
                    },
                    "idempotency_key": {
                      "type": "string",
                      "description": "The key sent with the request, unchanged. Null when none was sent.",
                      "example": "topup-20261023-0001",
                      "nullable": true
                    },
                    "address": {
                      "type": "string",
                      "description": "Deposit address. Send the exact amount here.",
                      "example": "YOUR_TRON_ADDRESS"
                    },
                    "amount_trx": {
                      "type": "string",
                      "description": "The exact sum, in currency. Send this sum, not the requested whole number. It equals the requested amount, or that amount plus 0.01 steps, up to 1 more, when the lower sums of this currency are already reserved. Six digits after the point.",
                      "example": "25.030000"
                    },
                    "currency": {
                      "$ref": "#/components/schemas/Currency"
                    },
                    "expires_at": {
                      "type": "string",
                      "description": "UTC timestamp, YYYY-MM-DDTHH:MM:SSZ. The window is one hour.",
                      "example": "2026-10-23T14:40:00Z"
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When the top-up was created, UTC, YYYY-MM-DDTHH:MM:SSZ.",
                      "example": "2026-10-23T13:40:00Z"
                    }
                  },
                  "required": [
                    "topup_id",
                    "idempotency_key",
                    "address",
                    "amount_trx",
                    "currency",
                    "expires_at",
                    "created_at"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "get": {
        "tags": [
          "Top-up"
        ],
        "operationId": "listTopups",
        "summary": "List unfinished top-ups",
        "description": "Returns every unfinished top-up on the account, newest first. Unfinished means pending, cooling, or seen. The call has no query parameters. An account has at most 5 unfinished top-ups. A credited or expired top-up is not in this list.",
        "responses": {
          "200": {
            "description": "A JSON array of unfinished top-ups.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "maxItems": 5,
                  "items": {
                    "$ref": "#/components/schemas/UnfinishedTopup"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/topup/{topup_id}": {
      "get": {
        "tags": [
          "Top-up"
        ],
        "operationId": "getTopup",
        "summary": "Read one top-up",
        "description": "Returns the status of one top-up and the deposit address. Send the exact amount to that address. A credited sum is also a deposit row on GET /api/v1/transaction.",
        "parameters": [
          {
            "name": "topup_id",
            "in": "path",
            "required": true,
            "description": "Top-up UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "b7e1d4a2-6c33-4a18-8b0d-5e2f1a0b9c8d"
          }
        ],
        "responses": {
          "200": {
            "description": "The top-up, any status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Topup"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/webhook": {
      "get": {
        "tags": [
          "Webhook"
        ],
        "operationId": "getWebhook",
        "summary": "Read the callback",
        "description": "Returns the callback address stored for this account. A cabinet session or a full key also receives the secret. A read-only key receives webhook_secret_set instead, and does not receive the secret. webhook_url is null when callbacks are off.",
        "responses": {
          "200": {
            "description": "The stored callback.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookConfig"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "Webhook"
        ],
        "operationId": "saveWebhook",
        "summary": "Save the callback",
        "description": "Saves the callback address and secret. An empty webhook_url turns callbacks off and clears the secret. https only, at most 2048 characters. Plain http, a loopback, a link-local, or a private address is rejected, and so is a name that does not resolve. The secret is at least 16 characters and at most 255, and is ignored when the URL is empty. A read-only key receives 403 key_read_only.",
        "requestBody": {
          "required": true,
          "description": "Callback. Use a placeholder secret. Do not send a real secret in shared examples.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Webhook save.",
                "properties": {
                  "webhook_url": {
                    "type": "string",
                    "description": "Optional. Omitted or empty turns callbacks off. https only, at most 2048 characters.",
                    "example": "https://example.com/gasrent",
                    "maxLength": 2048
                  },
                  "webhook_secret": {
                    "type": "string",
                    "description": "At least 16 characters, at most 255, when the URL is not empty. Placeholder only.",
                    "example": "replace-with-at-least-16-characters",
                    "maxLength": 255
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored callback, including the secret for a full key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSaved"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        },
        "callbacks": {
          "onEvent": {
            "{$request.body#/webhook_url}": {
              "post": {
                "summary": "Event posted to the callback URL",
                "description": "When webhook_url and a secret of at least 16 characters are both stored, gasrent sends POST with Content-Type application/json. The body bytes are the payload. X-Signature is the hex HMAC-SHA256 of those bytes, keyed with the secret. A response status from 200 to 299 completes the delivery. Any other result is retried. There are five attempts. The waits after a failed attempt are 60 seconds, 300 seconds, 900 seconds, and 3600 seconds. The fifth failure is not retried. Each event is queued once.",
                "parameters": [
                  {
                    "name": "X-Signature",
                    "in": "header",
                    "required": true,
                    "description": "Hex HMAC-SHA256 of the raw body bytes, keyed with the webhook secret.",
                    "schema": {
                      "type": "string"
                    }
                  }
                ],
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "oneOf": [
                          {
                            "$ref": "#/components/schemas/OrderWebhook"
                          },
                          {
                            "$ref": "#/components/schemas/BandwidthWebhook"
                          },
                          {
                            "$ref": "#/components/schemas/TopupWebhook"
                          },
                          {
                            "$ref": "#/components/schemas/ActivationWebhook"
                          }
                        ]
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Any status from 200 to 299 completes delivery."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/exchange": {
      "post": {
        "tags": [
          "Exchange"
        ],
        "operationId": "exchange",
        "summary": "Price or perform a TRX/USDT exchange",
        "description": "preview omitted or true prices the exchange and does not charge the balance. preview false performs it. The balance is charged first: the paid currency, then the TRX fee as its own ledger row. When the swap confirms, the received currency is credited with the amount the exchange actually delivered. Send fee_trx and receive_amount from the quote to lock them. If the fee has gone up, or the delivered amount is under 99 percent of receive_amount, the response is 409 price_changed and nothing is charged. Omit either field to accept the figure calculated on this call. The same idempotency key with the same currency and amount returns the original exchange. Idempotency applies when preview is false.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Exchange. preview defaults to true.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Exchange request.",
                "properties": {
                  "pay_currency": {
                    "$ref": "#/components/schemas/Currency"
                  },
                  "pay_amount": {
                    "type": "string",
                    "description": "Required. Positive decimal string with at most six digits after the point.",
                    "example": "10.5"
                  },
                  "preview": {
                    "type": "boolean",
                    "description": "Optional. Omitted means true. True prices the exchange and does not charge. False performs it.",
                    "example": true
                  },
                  "fee_trx": {
                    "type": "string",
                    "description": "Optional on a real exchange. Fee from the quote. May be zero. A higher fee than this returns 409 price_changed.",
                    "example": "1.200000"
                  },
                  "receive_amount": {
                    "type": "string",
                    "description": "Optional on a real exchange. Amount from the quote. If the delivered amount is under 99 percent of this, the response is 409 price_changed.",
                    "example": "2.150000"
                  },
                  "idempotency_key": {
                    "type": "string",
                    "description": "Optional. 8 to 128 characters. See the idempotency rules. Recommended. A dropped connection can be repeated safely only when the key is reused with the same body.",
                    "example": "exchange-20261026-0001",
                    "minLength": 8,
                    "maxLength": 128
                  }
                },
                "required": [
                  "pay_currency",
                  "pay_amount"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A preview, or the submitted exchange.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ExchangePreview"
                    },
                    {
                      "$ref": "#/components/schemas/Exchange"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/exchange/{id}": {
      "get": {
        "tags": [
          "Exchange"
        ],
        "operationId": "getExchange",
        "summary": "Read one exchange",
        "description": "Returns one exchange on this account. id is the UUID from the exchange that was placed. The fields are the same as a completed POST. While status is sending, receive_amount is still the quote. After sent, it is the amount credited.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Exchange UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "f1e2d3c4-b5a6-4789-8012-3456789abcde"
          }
        ],
        "responses": {
          "200": {
            "description": "The exchange.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Exchange"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/withdraw/quote": {
      "post": {
        "tags": [
          "Withdrawal"
        ],
        "operationId": "quoteWithdrawal",
        "summary": "Price a withdrawal",
        "description": "Prices a withdrawal without charging the balance. currency is trx or usdt. amount is a positive decimal string with at most six digits after the point. address is the TRON address that receives the payout. It must already be on the account withdrawal list and usable. Otherwise the response is 403 address_not_allowed or 403 address_locked. A withdrawal that would take the sum of the last 24 hours over the daily limit returns 403 daily_limit. The limit is 20000 TRX and 5000 USDT. Failed and refunded withdrawals do not count. If the balance of the chosen currency is already below amount, the quote does not ask the chain: fee_trx and debit_trx are null, can_submit is false, and short is that currency.",
        "requestBody": {
          "required": true,
          "description": "Withdrawal quote.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Withdrawal quote.",
                "properties": {
                  "currency": {
                    "$ref": "#/components/schemas/Currency"
                  },
                  "amount": {
                    "type": "string",
                    "description": "Required. Positive decimal string with at most six digits after the point.",
                    "example": "10.5"
                  },
                  "address": {
                    "type": "string",
                    "description": "Required. Tron address that receives the payout. It must be on the account list.",
                    "example": "YOUR_TRON_ADDRESS"
                  }
                },
                "required": [
                  "currency",
                  "amount",
                  "address"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The price. Nothing was charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WithdrawQuote"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/withdraw": {
      "post": {
        "tags": [
          "Withdrawal"
        ],
        "operationId": "createWithdrawal",
        "summary": "Withdraw TRX or USDT",
        "description": "Withdraws amount of currency to address. Send fee_trx and activation_trx from the quote. If either has gone up, the response is 409 price_changed and nothing is charged. If either has gone down, the lower figure is charged. Omit either field to accept the figure calculated on this call. When activation_trx is above zero, the activation is charged and sent first. Its balance row is separate from the withdrawal. If the payout later fails, the withdrawal is returned and the activation is not. USDT is debited from the USDT balance and the fee from the TRX balance. TRX debits the amount and the fee together, then sends the amount. The same idempotency key with the same currency, amount, and address returns the original withdrawal. A different currency, amount, or address returns 409 conflict. A 503 can arrive after the activation was already charged. The same idempotency key continues that activation and does not charge it again.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Withdrawal.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Withdrawal request.",
                "properties": {
                  "currency": {
                    "$ref": "#/components/schemas/Currency"
                  },
                  "amount": {
                    "type": "string",
                    "description": "Required. Positive decimal string with at most six digits after the point.",
                    "example": "10.5"
                  },
                  "address": {
                    "type": "string",
                    "description": "Required. Tron address on the account withdrawal list.",
                    "example": "YOUR_TRON_ADDRESS"
                  },
                  "fee_trx": {
                    "type": "string",
                    "description": "Optional. Fee from the quote. A higher fee returns 409 price_changed.",
                    "example": "0.270000"
                  },
                  "activation_trx": {
                    "type": "string",
                    "description": "Optional. Activation price from the quote. A higher price returns 409 price_changed. Zero when the address is already active.",
                    "example": "0.000000"
                  },
                  "idempotency_key": {
                    "type": "string",
                    "description": "Optional. 8 to 128 characters. See the idempotency rules. Recommended. A dropped connection can be repeated safely only when the key is reused with the same body.",
                    "example": "withdraw-20261026-0001",
                    "minLength": 8,
                    "maxLength": 128
                  }
                },
                "required": [
                  "currency",
                  "amount",
                  "address"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The withdrawal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Withdrawal"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/withdraw/address": {
      "get": {
        "tags": [
          "Withdrawal"
        ],
        "operationId": "listWithdrawAddresses",
        "summary": "List withdrawal addresses",
        "description": "A withdrawal goes only to an address from the account list. This call returns delay_hours and addresses. Adding and removing addresses is possible only from the cabinet, with a signed-in session. An API key can read the list. POST /api/v1/withdraw/address, POST /api/v1/withdraw/address/confirm, and DELETE /api/v1/withdraw/address/{id} with a key return 401 unauthorized. Those session methods are not part of this document.",
        "responses": {
          "200": {
            "description": "The address list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WithdrawAddressList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-KEY",
        "description": "API key issued in the cabinet. The full key is shown once, when it is issued. Use the placeholder YOUR_API_KEY in examples. GET /api/v1/health does not read this header."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "X-Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Optional. 8 to 128 characters. If idempotency_key is also set in the JSON body, the two values must be equal. The same key and the same body return the original result once that call has finished. The same key and a different body return 409 conflict. If the first call has not finished, the repeat waits and can return 503 unavailable.",
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 128
        }
      }
    },
    "responses": {
      "Error": {
        "description": "A failed call. The body is an error_code. The HTTP status is not 200. Codes are listed on https://gasrent.click/api.html.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error_code": "unauthorized"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Error body.",
        "properties": {
          "error_code": {
            "type": "string",
            "description": "Machine-readable code. 400 too_many_addresses, bad_request, bad_address, bad_destination, inactive_address, already_active, bad_duration, bad_volume, insufficient_usdt, transfer_reverted, bad_flags, bad_amount, bad_key, bad_webhook, volume_too_large, bad_code. 401 unauthorized. 402 insufficient_balance, insufficient_funds. 403 blocked, ip_not_allowed, key_read_only, address_not_allowed, address_locked, daily_limit. 404 not_found. 409 address_limit, conflict, price_changed. 429 rate_limited, too_many_topups. 500 internal. 503 offers_rejected, unavailable.",
            "example": "bad_request"
          }
        },
        "required": [
          "error_code"
        ]
      },
      "EnergyDuration": {
        "type": "string",
        "description": "Energy rental length. One of 15m, 1h, 1d, 3d. There is no 7-day energy rental.",
        "example": "1h",
        "enum": [
          "15m",
          "1h",
          "1d",
          "3d"
        ]
      },
      "BandwidthDuration": {
        "type": "string",
        "description": "Bandwidth rental length. One of 5m, 1h, 1d, 3d, 7d. There is no 15-minute bandwidth rental.",
        "example": "1h",
        "enum": [
          "5m",
          "1h",
          "1d",
          "3d",
          "7d"
        ]
      },
      "OrderStatus": {
        "type": "string",
        "description": "Pending, Filled, or Cancelled.",
        "example": "Pending",
        "enum": [
          "Pending",
          "Filled",
          "Cancelled"
        ]
      },
      "Currency": {
        "type": "string",
        "description": "trx or usdt.",
        "example": "trx",
        "enum": [
          "trx",
          "usdt"
        ]
      },
      "EnergyOrder": {
        "type": "object",
        "description": "One energy order.",
        "properties": {
          "order_id": {
            "type": "string",
            "description": "UUID of the order. This is the only order identifier.",
            "example": "a3f2c8e1-7b44-4d19-9c0e-6f1a2b3c4d5e",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key sent with the request, unchanged. Null when none was sent.",
            "example": "order-20261023-0001",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/OrderStatus"
          },
          "address": {
            "type": "string",
            "description": "Tron address that receives the energy.",
            "example": "YOUR_TRON_ADDRESS"
          },
          "volume": {
            "type": "integer",
            "description": "Energy on the order. It may be larger than the request when exact_volume is false. It is never smaller.",
            "example": 65000
          },
          "duration": {
            "$ref": "#/components/schemas/EnergyDuration"
          },
          "price_trx": {
            "type": "string",
            "description": "Full charge in TRX. Includes activation when activation is true. A later cancelled activation is removed from this total. A cancelled order returns the energy part. The activation fee stays charged unless that activation itself was cancelled. Six digits after the point.",
            "example": "1.911000"
          },
          "price_sun": {
            "type": "string",
            "description": "Sun for one energy. A fraction is kept, so price_sun x volume / 1000000 equals price_trx. When activation is included, the rate is taken from that combined total.",
            "example": "29.4"
          },
          "activation": {
            "type": "boolean",
            "description": "True when this order activated the address and price_trx includes that fee.",
            "example": false
          },
          "txid": {
            "type": "string",
            "description": "Present once the delegation transaction exists.",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "description": "When the order was created, UTC, YYYY-MM-DDTHH:MM:SS.sssZ.",
            "example": "2026-10-23T13:40:00.000Z"
          }
        },
        "required": [
          "order_id",
          "idempotency_key",
          "status",
          "address",
          "volume",
          "duration",
          "price_trx",
          "price_sun",
          "activation",
          "txid",
          "created_at"
        ]
      },
      "BandwidthOrder": {
        "type": "object",
        "description": "One bandwidth order.",
        "properties": {
          "order_id": {
            "type": "string",
            "description": "UUID of this bandwidth order. It is not an energy order id.",
            "example": "d5e6f708-1920-4a1b-8c2d-3e4f5a6b7c8d",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key sent with the request, unchanged. Null when none was sent.",
            "example": "bandwidth-20261025-0001",
            "nullable": true
          },
          "resource": {
            "type": "string",
            "description": "Always bandwidth.",
            "example": "bandwidth",
            "enum": [
              "bandwidth"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/OrderStatus"
          },
          "address": {
            "type": "string",
            "description": "Tron address that receives the bandwidth.",
            "example": "YOUR_TRON_ADDRESS"
          },
          "volume": {
            "type": "integer",
            "description": "Bandwidth on the order. It may be larger than the request when exact_volume is false. It is never smaller.",
            "example": 1000
          },
          "duration": {
            "$ref": "#/components/schemas/BandwidthDuration"
          },
          "price_trx": {
            "type": "string",
            "description": "Charge in TRX. A cancelled order returns this charge. Activation is not included. Six digits after the point.",
            "example": "0.801800"
          },
          "price_sun": {
            "type": "string",
            "description": "Sun for one bandwidth point. A fraction is kept, so price_sun x volume / 1000000 equals price_trx.",
            "example": "801.8"
          },
          "txid": {
            "type": "string",
            "description": "Present once the bandwidth delegation transaction exists.",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "description": "When the order was created, UTC, YYYY-MM-DDTHH:MM:SS.sssZ.",
            "example": "2026-10-23T13:40:00.000Z"
          }
        },
        "required": [
          "order_id",
          "idempotency_key",
          "resource",
          "status",
          "address",
          "volume",
          "duration",
          "price_trx",
          "price_sun",
          "txid",
          "created_at"
        ]
      },
      "Activation": {
        "type": "object",
        "description": "One activation.",
        "properties": {
          "activation_id": {
            "type": "string",
            "description": "UUID of this activation.",
            "example": "c4d8e2f1-1a22-4b33-8c44-7d5e6f708192",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key sent with the request, unchanged. Null when none was sent. Also null for an activation that an order or a withdrawal started by itself.",
            "example": "activation-20261023-0001",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/OrderStatus"
          },
          "address": {
            "type": "string",
            "description": "The Tron address.",
            "example": "YOUR_TRON_ADDRESS"
          },
          "price_trx": {
            "type": "string",
            "description": "Amount charged. Returned on Cancelled as well. The refund is a separate ledger row. Six digits after the point.",
            "example": "1.397000"
          },
          "txid": {
            "type": "string",
            "description": "The activation transaction.",
            "nullable": true
          }
        },
        "required": [
          "activation_id",
          "idempotency_key",
          "status",
          "address",
          "price_trx",
          "txid"
        ]
      },
      "UnfinishedTopup": {
        "type": "object",
        "description": "One unfinished top-up from GET /api/v1/topup. address and confirmations are not included.",
        "properties": {
          "topup_id": {
            "type": "string",
            "description": "UUID of the top-up.",
            "example": "b7e1d4a2-6c33-4a18-8b0d-5e2f1a0b9c8d",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key sent with the request, unchanged. Null when none was sent.",
            "example": "topup-20261023-0001",
            "nullable": true
          },
          "amount_trx": {
            "type": "string",
            "description": "The exact sum, six decimal places, in currency.",
            "example": "25.030000"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "status": {
            "type": "string",
            "description": "pending is waiting for the transfer. seen means the transfer is on the network and is waiting for 19 confirmations. cooling means the window has closed and a transfer that arrived in time can still be matched.",
            "example": "pending",
            "enum": [
              "pending",
              "seen",
              "cooling"
            ]
          },
          "expires_at": {
            "type": "string",
            "description": "UTC timestamp, YYYY-MM-DDTHH:MM:SSZ. The window is one hour.",
            "example": "2026-10-23T14:40:00Z"
          },
          "txid": {
            "type": "string",
            "description": "Set when status is seen. Cleared if that transfer disappears before it is credited.",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "description": "When the top-up was created, UTC, YYYY-MM-DDTHH:MM:SSZ.",
            "example": "2026-10-23T13:40:00Z"
          }
        },
        "required": [
          "topup_id",
          "idempotency_key",
          "amount_trx",
          "currency",
          "status",
          "expires_at",
          "txid",
          "created_at"
        ]
      },
      "Topup": {
        "type": "object",
        "description": "One top-up. GET /api/v1/topup returns unfinished rows only (pending, cooling, or seen) and omits address and confirmations. GET /api/v1/topup/{topup_id} can return any status.",
        "properties": {
          "topup_id": {
            "type": "string",
            "description": "UUID of the top-up.",
            "example": "b7e1d4a2-6c33-4a18-8b0d-5e2f1a0b9c8d",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key sent with the request, unchanged. Null when none was sent.",
            "example": "topup-20261023-0001",
            "nullable": true
          },
          "amount_trx": {
            "type": "string",
            "description": "The exact sum, in currency. Send this sum, not the requested whole number. It equals the requested amount, or that amount plus 0.01 steps, up to 1 more, when the lower sums of this currency are already reserved. Six digits after the point.",
            "example": "25.030000"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "status": {
            "type": "string",
            "description": "pending is waiting for the transfer. seen means the transfer is on the network and is waiting for 19 confirmations. cooling means the window has closed and a transfer that arrived in time can still be matched. credited means the sum is on the balance. expired means it was not matched.",
            "example": "pending",
            "enum": [
              "pending",
              "seen",
              "cooling",
              "credited",
              "expired"
            ]
          },
          "expires_at": {
            "type": "string",
            "description": "UTC timestamp, YYYY-MM-DDTHH:MM:SSZ. The window is one hour.",
            "example": "2026-10-23T14:40:00Z"
          },
          "txid": {
            "type": "string",
            "description": "Set when status is seen or credited. Cleared if that transfer disappears before it is credited.",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "description": "When the top-up was created, UTC, YYYY-MM-DDTHH:MM:SSZ.",
            "example": "2026-10-23T13:40:00Z"
          },
          "address": {
            "type": "string",
            "description": "Deposit address. Send the exact amount here. Omitted when the service has no deposit address configured. Omitted from the unfinished list.",
            "example": "YOUR_TRON_ADDRESS"
          },
          "confirmations": {
            "type": "integer",
            "description": "Present only when status is seen and the chain answered. How many blocks the transfer is behind the current head. 0 means the transfer is in the latest block. The top-up is credited when this reaches 19. Omitted when the chain did not answer.",
            "example": 7
          }
        },
        "required": [
          "topup_id",
          "idempotency_key",
          "amount_trx",
          "currency",
          "status",
          "expires_at",
          "txid",
          "created_at"
        ]
      },
      "Balance": {
        "type": "object",
        "description": "Spendable balances. Energy, bandwidth, and activation use TRX. USDT is a separate balance.",
        "properties": {
          "balance": {
            "type": "string",
            "description": "Spendable TRX balance. Same value as the trx entry in balances. Six digits after the point.",
            "example": "12.500000"
          },
          "balances": {
            "type": "array",
            "description": "Every currency, including TRX.",
            "items": {
              "type": "object",
              "description": "One currency balance.",
              "properties": {
                "currency": {
                  "$ref": "#/components/schemas/Currency"
                },
                "balance": {
                  "type": "string",
                  "description": "Balance of that currency. Six digits after the point.",
                  "example": "12.500000"
                }
              },
              "required": [
                "currency",
                "balance"
              ]
            },
            "example": [
              {
                "currency": "trx",
                "balance": "12.500000"
              },
              {
                "currency": "usdt",
                "balance": "0.000000"
              }
            ]
          },
          "email": {
            "type": "string",
            "description": "The account email.",
            "example": "ada@example.com"
          },
          "saved_trx": {
            "type": "string",
            "description": "Sum over filled orders of the TRX the network would have burned for the energy sold, minus the price paid. The burn price is the chain energy fee in force when the order was created. The figure can be negative. Six digits after the point.",
            "example": "3.150000"
          }
        },
        "required": [
          "balance",
          "balances",
          "email",
          "saved_trx"
        ]
      },
      "Transaction": {
        "type": "object",
        "description": "One balance movement. A row that does not change the balance is omitted.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Public id of this ledger row. The numeric id is not included.",
            "example": "e1f2a3b4-c5d6-4789-a012-3456789abcde",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "description": "deposit is a top-up. debit is a charge for energy, bandwidth, or activating an address. refund returns part or all of a charge. adjustment is a manual change. exchange is one leg of a USDT/TRX exchange: the amount paid, the TRX fee, or the amount received. withdrawal is a payout of TRX or USDT. supply is TRX paid for energy this account rented out. reward is voting rewards credited in TRX. reward_out is those rewards sent on to the wallet. affiliate is an affiliate commission in TRX. resource says whether a debit or refund belongs to energy or bandwidth.",
            "example": "deposit"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "amount": {
            "type": "string",
            "description": "Signed amount in currency, six digits after the point. A charge is negative.",
            "example": "-25.030000"
          },
          "amount_trx": {
            "type": "string",
            "description": "Signed TRX effect of this row. Equal to amount when currency is trx, and 0.000000 when the row is USDT.",
            "example": "-25.030000"
          },
          "balance_after": {
            "type": "string",
            "description": "The TRX balance after this row, including a row that did not change TRX. Six digits after the point.",
            "example": "37.530000"
          },
          "currency_balance_after": {
            "type": "string",
            "description": "The balance of currency after this row. Six digits after the point.",
            "example": "37.530000"
          },
          "uuid": {
            "type": "string",
            "description": "UUID of the energy or bandwidth order the client can open. Null when this row is not such an order. resource says which. The numeric order id is not included.",
            "example": "a3f2c8e1-7b44-4d19-9c0e-6f1a2b3c4d5e",
            "nullable": true
          },
          "resource": {
            "type": "string",
            "description": "energy or bandwidth when uuid is an order. Null for a top-up, an activation, or an adjustment.",
            "example": "energy",
            "nullable": true
          },
          "topup_id": {
            "type": "string",
            "description": "UUID of the top-up, when this row belongs to one.",
            "example": "b7e1d4a2-6c33-4a18-8b0d-5e2f1a0b9c8d",
            "nullable": true
          },
          "activation_id": {
            "type": "string",
            "description": "UUID of the activation, when this row belongs to one.",
            "example": "c4d8e2f1-1a22-4b33-8c44-7d5e6f708192",
            "nullable": true
          },
          "energy": {
            "type": "integer",
            "description": "Energy of the rental this row pays for, on a supply row. Null on every other row. The buyer and the order are not shown.",
            "example": 65000,
            "nullable": true
          },
          "duration": {
            "type": "string",
            "description": "Length of that rental, such as 1h or 1d, on a supply row. Null on every other row.",
            "example": "1h",
            "nullable": true
          },
          "related_id": {
            "type": "string",
            "description": "Public id of the earlier ledger row this row continues, or null.",
            "nullable": true
          },
          "txid": {
            "type": "string",
            "description": "The chain transaction for a deposit or an activation.",
            "nullable": true
          },
          "comment": {
            "type": "string",
            "description": "A note on this row, usually on an adjustment.",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "description": "UTC timestamp, YYYY-MM-DDTHH:MM:SS.sssZ.",
            "example": "2026-10-23T13:40:00.000Z"
          }
        },
        "required": [
          "id",
          "kind",
          "currency",
          "amount",
          "amount_trx",
          "balance_after",
          "currency_balance_after",
          "uuid",
          "resource",
          "topup_id",
          "activation_id",
          "energy",
          "duration",
          "related_id",
          "txid",
          "comment",
          "created_at"
        ]
      },
      "TransactionPage": {
        "type": "object",
        "description": "One page of balance movements.",
        "properties": {
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transaction"
            }
          },
          "total": {
            "type": "integer",
            "description": "How many rows match before paging.",
            "example": 3
          },
          "page": {
            "type": "integer",
            "description": "The page that was returned. Starts at 1.",
            "example": 1
          },
          "limit": {
            "type": "integer",
            "description": "The page size that was used.",
            "example": 50
          }
        },
        "required": [
          "transactions",
          "total",
          "page",
          "limit"
        ]
      },
      "WebhookConfig": {
        "type": "object",
        "description": "Callback stored for the account. A cabinet session or a full key also receives webhook_secret. A read-only key receives webhook_secret_set instead and does not receive the secret.",
        "properties": {
          "webhook_url": {
            "type": "string",
            "description": "The address gasrent posts to. Null when callbacks are off.",
            "example": "https://example.com/gasrent",
            "nullable": true
          },
          "webhook_secret": {
            "type": "string",
            "description": "The HMAC key. Present for a cabinet session or a full key. At least 16 characters when a URL is set, and null when callbacks are off. Omitted for a read-only key.",
            "example": "replace-with-at-least-16-characters",
            "nullable": true
          },
          "webhook_secret_set": {
            "type": "boolean",
            "description": "Present only for a read-only key. True when a secret is stored. The secret itself is not included.",
            "example": true
          }
        },
        "required": [
          "webhook_url"
        ]
      },
      "WebhookSaved": {
        "type": "object",
        "description": "Callback written by POST /api/v1/webhook. A read-only key cannot call this method, so the secret is included.",
        "properties": {
          "webhook_url": {
            "type": "string",
            "description": "The address gasrent posts to. Null when callbacks are off.",
            "example": "https://example.com/gasrent",
            "nullable": true
          },
          "webhook_secret": {
            "type": "string",
            "description": "The HMAC key, at least 16 characters when a URL is set. Null when callbacks are off.",
            "example": "replace-with-at-least-16-characters",
            "nullable": true
          }
        },
        "required": [
          "webhook_url",
          "webhook_secret"
        ]
      },
      "EnergyEstimate": {
        "type": "object",
        "description": "Energy and bandwidth one or more USDT transfers would use. Does not buy anything and does not return a price.",
        "properties": {
          "available_energy": {
            "type": "integer",
            "description": "Energy available on from_address.",
            "example": 12000
          },
          "required_energy": {
            "type": "integer",
            "description": "Energy the whole request would use. The gap is this minus available_energy.",
            "example": 64285
          },
          "free_bandwidth": {
            "type": "integer",
            "description": "Free daily bandwidth left on from_address. It pays for the transfer only when it covers the whole transfer by itself.",
            "example": 300
          },
          "delegated_bandwidth": {
            "type": "integer",
            "description": "Delegated bandwidth left on from_address. A rental adds to this pool.",
            "example": 100
          },
          "available_bandwidth": {
            "type": "integer",
            "description": "Bandwidth that already counts toward this transfer. When either pool covers the transfer, this is the larger pool. Otherwise it is only delegated_bandwidth, because the pools are not added together. For a batch, the free pool covers as many whole transfers as fit in it. The remaining transfers need the delegated pool.",
            "example": 100
          },
          "required_bandwidth": {
            "type": "integer",
            "description": "Bandwidth points the whole request would use: 345 for each USDT transfer without a note.",
            "example": 345
          },
          "transfers": {
            "type": "array",
            "description": "Only when the request used to_addresses. One item per transfer, in request order. The items add up to required_energy.",
            "items": {
              "type": "object",
              "description": "One simulated transfer.",
              "properties": {
                "to_address": {
                  "type": "string",
                  "description": "Recipient of this transfer.",
                  "example": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
                },
                "required_energy": {
                  "type": "integer",
                  "description": "Energy this transfer would use.",
                  "example": 64285
                }
              },
              "required": [
                "to_address",
                "required_energy"
              ]
            }
          }
        },
        "required": [
          "available_energy",
          "required_energy",
          "free_bandwidth",
          "delegated_bandwidth",
          "available_bandwidth",
          "required_bandwidth"
        ]
      },
      "ExchangePreview": {
        "type": "object",
        "description": "A priced exchange that does not charge the balance.",
        "properties": {
          "preview": {
            "type": "boolean",
            "description": "True. The balance was not charged.",
            "example": true
          },
          "can_submit": {
            "type": "boolean",
            "description": "True only when the balance covers the debit and the exchange can be filled.",
            "example": true
          },
          "short": {
            "type": "string",
            "description": "trx, usdt, fee, or wallet. fee means a USDT payment where the TRX balance plus 99 percent of the TRX the swap would return is still below the fee. wallet means the exchange cannot be filled right now. Null when can_submit is true.",
            "nullable": true,
            "enum": [
              "trx",
              "usdt",
              "fee",
              "wallet"
            ]
          },
          "pay_currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "pay_amount": {
            "type": "string",
            "description": "Positive decimal with at most six digits after the point.",
            "example": "10.500000"
          },
          "receive_currency": {
            "type": "string",
            "description": "trx or usdt. The currency that would be received, the opposite of pay_currency.",
            "example": "usdt",
            "enum": [
              "trx",
              "usdt"
            ]
          },
          "receive_amount": {
            "type": "string",
            "description": "What the exchange would deliver, six digits after the point. It can move a little before the swap is sent. After status sent, this is the amount credited.",
            "example": "2.150000"
          },
          "fee_trx": {
            "type": "string",
            "description": "Energy rental for the swap, plus the bandwidth of the swap. The bandwidth is always included. The fee is not folded into the rate. Six digits after the point.",
            "example": "1.200000"
          },
          "debit_trx": {
            "type": "string",
            "description": "TRX that would leave the balance. For TRX paid in, the amount plus the fee. For USDT paid in, only the fee. Six digits after the point.",
            "example": "11.700000"
          },
          "debit_usdt": {
            "type": "string",
            "description": "USDT that would leave the balance. The pay amount when pay_currency is usdt, otherwise 0.000000. Six digits after the point.",
            "example": "0.000000"
          },
          "credit_trx": {
            "type": "string",
            "description": "TRX that would be added. 0.000000 when the received currency is USDT. Six digits after the point.",
            "example": "0.000000"
          },
          "credit_usdt": {
            "type": "string",
            "description": "USDT that would be added. 0.000000 when the received currency is TRX. Six digits after the point.",
            "example": "2.150000"
          }
        },
        "required": [
          "preview",
          "pay_currency",
          "pay_amount",
          "receive_currency",
          "receive_amount",
          "fee_trx",
          "debit_trx",
          "debit_usdt",
          "credit_trx",
          "credit_usdt",
          "can_submit",
          "short"
        ]
      },
      "Exchange": {
        "type": "object",
        "description": "An exchange that was submitted. While status is sending, receive_amount is still the quote. After sent, it is the amount credited.",
        "properties": {
          "preview": {
            "type": "boolean",
            "description": "False. The exchange was submitted.",
            "example": false
          },
          "id": {
            "type": "string",
            "description": "Exchange UUID.",
            "example": "f1e2d3c4-b5a6-4789-8012-3456789abcde",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key sent with the request, unchanged. Null when none was sent.",
            "example": "exchange-20261026-0001",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "sending, sent, review, or failed. failed means the charge was refunded.",
            "example": "sending",
            "enum": [
              "sending",
              "sent",
              "review",
              "failed"
            ]
          },
          "txid": {
            "type": "string",
            "description": "The swap transaction, when one exists.",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "description": "When it was created, UTC, YYYY-MM-DDTHH:MM:SSZ.",
            "example": "2026-10-26T13:40:00Z"
          },
          "pay_currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "pay_amount": {
            "type": "string",
            "description": "Positive decimal with at most six digits after the point.",
            "example": "10.500000"
          },
          "receive_currency": {
            "type": "string",
            "description": "trx or usdt. The currency that would be received, the opposite of pay_currency.",
            "example": "usdt",
            "enum": [
              "trx",
              "usdt"
            ]
          },
          "receive_amount": {
            "type": "string",
            "description": "What the exchange would deliver, six digits after the point. It can move a little before the swap is sent. After status sent, this is the amount credited.",
            "example": "2.150000"
          },
          "fee_trx": {
            "type": "string",
            "description": "Energy rental for the swap, plus the bandwidth of the swap. The bandwidth is always included. The fee is not folded into the rate. Six digits after the point.",
            "example": "1.200000"
          },
          "debit_trx": {
            "type": "string",
            "description": "TRX that would leave the balance. For TRX paid in, the amount plus the fee. For USDT paid in, only the fee. Six digits after the point.",
            "example": "11.700000"
          },
          "debit_usdt": {
            "type": "string",
            "description": "USDT that would leave the balance. The pay amount when pay_currency is usdt, otherwise 0.000000. Six digits after the point.",
            "example": "0.000000"
          },
          "credit_trx": {
            "type": "string",
            "description": "TRX that would be added. 0.000000 when the received currency is USDT. Six digits after the point.",
            "example": "0.000000"
          },
          "credit_usdt": {
            "type": "string",
            "description": "USDT that would be added. 0.000000 when the received currency is TRX. Six digits after the point.",
            "example": "2.150000"
          }
        },
        "required": [
          "preview",
          "id",
          "idempotency_key",
          "status",
          "pay_currency",
          "pay_amount",
          "receive_currency",
          "receive_amount",
          "fee_trx",
          "debit_trx",
          "debit_usdt",
          "credit_trx",
          "credit_usdt",
          "txid",
          "created_at"
        ]
      },
      "WithdrawQuote": {
        "type": "object",
        "description": "A withdrawal price. Does not charge the balance.",
        "properties": {
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "amount": {
            "type": "string",
            "description": "Amount that would be sent, six digits after the point.",
            "example": "10.500000"
          },
          "address": {
            "type": "string",
            "description": "Tron address that would receive the payout.",
            "example": "YOUR_TRON_ADDRESS"
          },
          "fee_trx": {
            "type": "string",
            "description": "For USDT, the higher of the 15-minute energy rental that will be bought and a 1-hour quote for the same energy. A destination that already holds USDT costs less energy. For TRX, the chain burn for 270 bandwidth points plus the account markup. Free bandwidth on the address is not used. Does not include activation. Null when the balance of the chosen currency is already below amount: the quote does not ask the chain. Six digits after the point.",
            "example": "0.270000",
            "nullable": true
          },
          "debit_trx": {
            "type": "string",
            "description": "TRX that would leave the balance: the fee and the activation for USDT, or the amount plus both for TRX. Null when the quote is not priced. Six digits after the point.",
            "example": "10.770000",
            "nullable": true
          },
          "energy": {
            "type": "integer",
            "description": "Energy a USDT payout would use. Null for a TRX payout, and null when the quote is not priced.",
            "example": 64285,
            "nullable": true
          },
          "bandwidth": {
            "type": "integer",
            "description": "Bandwidth points a TRX payout would use. Null for a USDT payout, and null when the quote is not priced.",
            "example": 270,
            "nullable": true
          },
          "activation": {
            "type": "boolean",
            "description": "True when address is not activated yet. The activation price is charged as its own activation before the payout.",
            "example": false
          },
          "activation_trx": {
            "type": "string",
            "description": "Activation price. Zero when the address is already active. Not included in fee_trx. Six digits after the point.",
            "example": "0.000000"
          },
          "can_submit": {
            "type": "boolean",
            "description": "True only when the balance covers the charge.",
            "example": true
          },
          "short": {
            "type": "string",
            "description": "trx, usdt, or both when the balance does not cover the charge. Null when can_submit is true.",
            "nullable": true,
            "enum": [
              "trx",
              "usdt",
              "both"
            ]
          }
        },
        "required": [
          "currency",
          "amount",
          "address",
          "fee_trx",
          "debit_trx",
          "energy",
          "bandwidth",
          "activation",
          "activation_trx",
          "can_submit",
          "short"
        ]
      },
      "Withdrawal": {
        "type": "object",
        "description": "A withdrawal. sending means the payout is still going out and can already have a txid. review means the payout is being checked and can already have a txid. sent means the network accepted the payout. failed means the charge was returned.",
        "properties": {
          "withdrawal_id": {
            "type": "string",
            "description": "Public id of the withdrawal.",
            "example": "a9b8c7d6-e5f4-4123-9456-7890abcdef12",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key sent with the request, unchanged. Null when none was sent.",
            "example": "withdraw-20261026-0001",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "sending, sent, review, or failed.",
            "example": "sending",
            "enum": [
              "sending",
              "sent",
              "review",
              "failed"
            ]
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "amount": {
            "type": "string",
            "description": "Amount sent, or to be sent, six digits after the point.",
            "example": "10.500000"
          },
          "fee_trx": {
            "type": "string",
            "description": "Fee charged. If the quoted fee has gone down, the lower figure is charged. Six digits after the point.",
            "example": "0.270000"
          },
          "activation": {
            "type": "boolean",
            "description": "True when an activation was charged for this payout.",
            "example": false
          },
          "activation_trx": {
            "type": "string",
            "description": "Activation price charged, or zero. Six digits after the point.",
            "example": "0.000000"
          },
          "activation_id": {
            "type": "string",
            "description": "Public id of the activation, or null.",
            "nullable": true
          },
          "debit_trx": {
            "type": "string",
            "description": "TRX that left the balance, including activation. Six digits after the point.",
            "example": "10.770000"
          },
          "address": {
            "type": "string",
            "description": "Tron address that receives the payout.",
            "example": "YOUR_TRON_ADDRESS"
          },
          "txid": {
            "type": "string",
            "description": "Payout transaction. Present when status is sent.",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "description": "When the withdrawal was created, UTC, YYYY-MM-DDTHH:MM:SS.sssZ.",
            "example": "2026-10-26T13:40:00.000Z"
          }
        },
        "required": [
          "withdrawal_id",
          "idempotency_key",
          "status",
          "currency",
          "amount",
          "fee_trx",
          "activation",
          "activation_trx",
          "activation_id",
          "debit_trx",
          "address",
          "txid",
          "created_at"
        ]
      },
      "WithdrawAddressList": {
        "type": "object",
        "description": "Withdrawal addresses on the account. A payout goes only to an address from this list.",
        "properties": {
          "delay_hours": {
            "type": "integer",
            "description": "Hours after confirmation before a new address becomes usable. 24 by default.",
            "example": 24
          },
          "addresses": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "One withdrawal address.",
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "Numeric id of the address row.",
                  "example": 1
                },
                "address": {
                  "type": "string",
                  "description": "Tron address.",
                  "example": "YOUR_TRON_ADDRESS"
                },
                "status": {
                  "type": "string",
                  "description": "pending waits for the emailed code. active is confirmed.",
                  "example": "active",
                  "enum": [
                    "pending",
                    "active"
                  ]
                },
                "usable": {
                  "type": "boolean",
                  "description": "True when a withdrawal to this address is allowed now.",
                  "example": true
                },
                "active_from": {
                  "type": "string",
                  "description": "UTC, YYYY-MM-DDTHH:MM:SS.sssZ, or null while pending. A new address becomes usable delay_hours after it is confirmed.",
                  "example": "2026-10-26T13:40:00.000Z",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "address",
                "status",
                "usable",
                "active_from"
              ]
            }
          }
        },
        "required": [
          "delay_hours",
          "addresses"
        ]
      },
      "OrderWebhook": {
        "type": "object",
        "description": "order.filled or order.cancelled. gasrent POSTs this JSON to the stored callback URL.",
        "properties": {
          "event": {
            "type": "string",
            "description": "order.filled or order.cancelled.",
            "example": "order.filled",
            "enum": [
              "order.filled",
              "order.cancelled"
            ]
          },
          "order_id": {
            "type": "string",
            "description": "UUID of the order that finished.",
            "example": "a3f2c8e1-7b44-4d19-9c0e-6f1a2b3c4d5e",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key the client sent when this was created, unchanged. Null when none was sent.",
            "example": "order-20261023-0001",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "Filled or Cancelled.",
            "example": "Filled",
            "enum": [
              "Filled",
              "Cancelled"
            ]
          },
          "price_trx": {
            "type": "string",
            "description": "The same total as the order at send time. Includes activation when this order activated the address. Six digits after the point.",
            "example": "1.911000"
          },
          "txid": {
            "type": "string",
            "description": "The delegation transaction, when one exists.",
            "nullable": true
          }
        },
        "required": [
          "event",
          "order_id",
          "idempotency_key",
          "status",
          "price_trx",
          "txid"
        ]
      },
      "BandwidthWebhook": {
        "type": "object",
        "description": "bandwidth.filled or bandwidth.cancelled. These are not order.filled or order.cancelled.",
        "properties": {
          "event": {
            "type": "string",
            "description": "bandwidth.filled or bandwidth.cancelled.",
            "example": "bandwidth.filled",
            "enum": [
              "bandwidth.filled",
              "bandwidth.cancelled"
            ]
          },
          "resource": {
            "type": "string",
            "description": "Always bandwidth.",
            "example": "bandwidth",
            "enum": [
              "bandwidth"
            ]
          },
          "order_id": {
            "type": "string",
            "description": "UUID of the bandwidth order that finished.",
            "example": "d5e6f708-1920-4a1b-8c2d-3e4f5a6b7c8d",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key the client sent when this was created. Null when none was sent.",
            "example": "bandwidth-20261025-0001",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "Filled or Cancelled.",
            "example": "Filled",
            "enum": [
              "Filled",
              "Cancelled"
            ]
          },
          "volume": {
            "type": "integer",
            "description": "The bandwidth on the order.",
            "example": 1000
          },
          "duration": {
            "$ref": "#/components/schemas/BandwidthDuration"
          },
          "price_trx": {
            "type": "string",
            "description": "The charge at send time. A cancelled order has already returned it. Six digits after the point.",
            "example": "0.801800"
          },
          "txid": {
            "type": "string",
            "description": "The bandwidth delegation transaction, when one exists.",
            "nullable": true
          }
        },
        "required": [
          "event",
          "resource",
          "order_id",
          "idempotency_key",
          "status",
          "volume",
          "duration",
          "price_trx",
          "txid"
        ]
      },
      "TopupWebhook": {
        "type": "object",
        "description": "topup.credited.",
        "properties": {
          "event": {
            "type": "string",
            "description": "topup.credited.",
            "example": "topup.credited",
            "enum": [
              "topup.credited"
            ]
          },
          "topup_id": {
            "type": "string",
            "description": "UUID of the top-up that was credited.",
            "example": "b7e1d4a2-6c33-4a18-8b0d-5e2f1a0b9c8d",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key the client sent when this was created. Null when none was sent.",
            "example": "topup-20261023-0001",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "credited.",
            "example": "credited",
            "enum": [
              "credited"
            ]
          },
          "amount_trx": {
            "type": "string",
            "description": "Amount credited, in currency. Six digits after the point.",
            "example": "25.030000"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "txid": {
            "type": "string",
            "description": "The deposit transaction.",
            "nullable": true
          }
        },
        "required": [
          "event",
          "topup_id",
          "idempotency_key",
          "status",
          "amount_trx",
          "currency",
          "txid"
        ]
      },
      "ActivationWebhook": {
        "type": "object",
        "description": "activation.filled or activation.cancelled. Cancelled means the charge was returned.",
        "properties": {
          "event": {
            "type": "string",
            "description": "activation.filled or activation.cancelled.",
            "example": "activation.filled",
            "enum": [
              "activation.filled",
              "activation.cancelled"
            ]
          },
          "activation_id": {
            "type": "string",
            "description": "UUID of the activation.",
            "example": "c4d8e2f1-1a22-4b33-8c44-7d5e6f708192",
            "format": "uuid"
          },
          "idempotency_key": {
            "type": "string",
            "description": "The key the client sent when this was created. Null when none was sent. Also null for an activation that an order or a withdrawal started by itself.",
            "example": "activation-20261023-0001",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "Filled or Cancelled.",
            "example": "Filled",
            "enum": [
              "Filled",
              "Cancelled"
            ]
          },
          "address": {
            "type": "string",
            "description": "The Tron address.",
            "example": "YOUR_TRON_ADDRESS"
          },
          "price_trx": {
            "type": "string",
            "description": "Activation price. Six digits after the point.",
            "example": "1.397000"
          },
          "txid": {
            "type": "string",
            "description": "The activation transaction.",
            "nullable": true
          }
        },
        "required": [
          "event",
          "activation_id",
          "idempotency_key",
          "status",
          "address",
          "price_trx",
          "txid"
        ]
      }
    }
  }
}
