> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sqd.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Tron SQD Network API

> Query Tron data from SQD Network directly — router and worker HTTP API reference.

[Open private SQD Network](/en/network/overview) offers access to Tron data. The gateway is at

```
https://v2.archive.subsquid.io/network/tron-mainnet
```

<Warning>
  V2 gateway worker requests require an API key. Get one at [portal.sqd.dev](https://portal.sqd.dev) and pass it in an `Authorization: Bearer <key>` header. `GET /height` on the router works without a key.
</Warning>

SQD Network API distributes the requests over a ([potentially decentralized](/en/other/faq)) network of *workers*. The main gateway URL points at a *router* that provides URLs of workers that do the heavy lifting. Each worker has its own range of blocks.

Suppose you want to retrieve an output of some [query](#worker-api) on a block range starting at `firstBlock` (can be the genesis block) and ending at the highest available block. Proceed as follows:

1. Retrieve the dataset height from the router with `GET /height` and make sure it's above `firstBlock`.

2. Save the value of `firstBlock` to some variable, say `currentBlock`.

3. Query the router for an URL of a worker that has the data for `currentBlock` with `GET /${currentBlock}/worker`.

4. Retrieve the data from the worker by [posting the query](#worker-api) (`POST /`), setting the `"fromBlock"` query field to `${currentBlock}`.

5. Parse the retrieved data to get a batch of query data **plus** the height of the last block available from the current worker. Take the `header.number` field of the last element of the retrieved JSON array - it is the height you want. Even if your query returns no data, you'll still get the block data for the last block in the range, so this procedure is safe.

6. Set `currentBlock` to the height from the previous step **plus one**.

7. Repeat steps 3-6 until all the required data is retrieved.

Implementation examples:

<AccordionGroup>
  <Accordion title="Manually with cURL">
    Suppose we want all [token burns](https://developers.tron.network/docs/faq#3-what-is-the-destruction-address-of-tron) starting from block 58\_000\_000. We have to:

    1. Verify that the dataset has reached the required height:
       ```bash theme={"system"}
       curl https://v2.archive.subsquid.io/network/tron-mainnet/height
       ```
       Output
       ```
       84700964
       ```

    2. Remember that your current height is 58000000.

    3. Get a worker URL for the current height
       ```bash theme={"system"}
       curl -H "Authorization: Bearer $SQD_API_KEY" \
         https://v2.archive.subsquid.io/network/tron-mainnet/58000000/worker
       ```
       Output is a worker URL, e.g.
       ```
       https://rb03.sqd-archive.net/worker/query/czM6Ly90cm9uLW1haW5uZXQ
       ```

    4. Retrieve the data from the worker
       ```bash theme={"system"}
       curl https://rb03.sqd-archive.net/worker/query/czM6Ly90cm9uLW1haW5uZXQ \
       -X 'POST' -H 'content-type: application/json' -H 'accept: application/json' \
       -H "Authorization: Bearer $SQD_API_KEY" \
       -d '{
           "fromBlock":58000000,
           "fields":{"transaction":{"hash":true}},
           "transferTransactions":[{
             "to":[
               "410000000000000000000000000000000000000000"
             ]
           }]
       }' | jq
       ```
       The output is a JSON array of per-block data. Its last element holds the highest block available from this worker:
       ```json theme={"system"}
       [
         {
           "header": {
             "number": 58000000,
             "hash": "0000000003750080...",
             "parentHash": "000000000375007f..."
           },
           "transactions": []
         },
         // ...
         {
           "header": { "number": ..., "hash": "...", "parentHash": "..." },
           "transactions": [ { "transactionIndex": ..., "hash": "..." } ]
         }
       ]
       ```

    5. Observe the `header.number` of the last list item, say `59286799`. To get the rest of the data, request a worker that has blocks from 59286800 on:
       ```bash theme={"system"}
       curl -H "Authorization: Bearer $SQD_API_KEY" \
         https://v2.archive.subsquid.io/network/tron-mainnet/59286800/worker
       ```
       This part of the dataset may be located on another host.

    6. Repeat steps 4 and 5 until the dataset height is reached.
  </Accordion>

  <Accordion title="In Python">
    ```python theme={"system"}
    def get_text(url: str) -> str:
        res = requests.get(url)
        res.raise_for_status()
        return res.text

    def dump(
        dataset_url: str,
        query: Query,
        first_block: int,
        last_block: int
    ) -> None:
        assert 0 <= first_block <= last_block
        query = dict(query)  # copy query to mess with it later

        dataset_height = int(get_text(f'{dataset_url}/height'))
        next_block = first_block
        last_block = min(last_block, dataset_height)

        while next_block <= last_block:
            worker_url = get_text(f'{dataset_url}/{next_block}/worker')

            query['fromBlock'] = next_block
            query['toBlock'] = last_block
            res = requests.post(worker_url, json=query)
            res.raise_for_status()
            blocks = res.json()

            last_processed_block = blocks[-1]['header']['number']
            next_block = last_processed_block + 1
            for block in blocks:
                print(json.dumps(block))
    ```

    Full code [here](https://gist.github.com/eldargab/2e007a293ac9f82031d023f1af581a7d).
  </Accordion>
</AccordionGroup>

## Router API

<AccordionGroup>
  <Accordion title="GET /height (get height of the dataset)">
    **Example response:** `84700964`.
  </Accordion>

  <Accordion title="GET ${firstBlock}/worker (get a suitable worker URL)">
    The returned worker will be capable of processing `POST /` requests in which the `"fromBlock"` field is equal to `${firstBlock}`.

    **Example response:** `https://rb06.sqd-archive.net/worker/query/czM6Ly90cm9uLW1haW5uZXQ`.
  </Accordion>
</AccordionGroup>

## Worker API

<Accordion title="POST / (query logs and transactions)">
  ##### Query Fields

  * **fromBlock**: Block number to start from (inclusive).
  * **toBlock**: (optional) Block number to end on (inclusive). If this is not given, the query will go on for a fixed amount of time or until it reaches the height of the dataset.
  * **includeAllBlocks**: (optional) If true, the Network will include blocks that contain no data selected by data requests into its response.
  * **fields**: (optional) A [selector](#data-fields-selector) of data fields to retrieve. Common for all data items.
  * **logs**: (optional) A list of [log requests](#logs). An empty list requests no data.
  * **transactions**: (optional) A list of [general transaction requests](#general-transactions). An empty list requests no data.
  * **transferTransactions**: (optional) A list of ["transfer" transaction requests](#transfer-transactions). An empty list requests no data.
  * **transferAssetTransactions**: (optional) A list of ["transfer asset" transaction requests](#transfer-asset-transactions). An empty list requests no data.
  * **triggerSmartContractTransactions**: (optional) A list of ["trigger smart contract" transaction requests](#trigger-smart-contract-transactions). An empty list requests no data.
  * **internalTransactions**: (optional) A list of [internal transaction requests](#internal-transactions). An empty list requests no data.

  <Accordion title="Example Request">
    This requests USDT `Transfer(address,address,uint256)` event logs together with their parent transactions on a single block:

    ```json theme={"system"}
    {
      "logs": [
        {
          "address": [
            "a614f803b6fd780986a42c78ec9c7f77e6ded13c"
          ],
          "topic0": [
            "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
          ],
          "transaction": true
        }
      ],
      "fields": {
        "block": {
          "timestamp": true
        },
        "log": {
          "topics": true,
          "data": true
        },
        "transaction": {
          "hash": true
        }
      },
      "fromBlock": 64000000,
      "toBlock": 64000000
    }
    ```
  </Accordion>

  The response is a JSON array of per-block items shaped as

  ```json theme={"system"}
  [
    {
      "header": { "number": 64000000, "hash": "...", "parentHash": "...", "timestamp": ... },
      "transactions": [ { "transactionIndex": ..., "hash": "..." } ],
      "logs": [
        {
          "logIndex": ...,
          "transactionIndex": ...,
          "topics": [ "ddf252ad...", "..." ],
          "data": "..."
        }
      ]
    }
  ]
  ```

  with `header.number`, `header.hash` and `header.parentHash` always present and the rest of the fields as requested by the [fields selector](#data-fields-selector).
</Accordion>

## Data requests

<Warning>
  Addresses in all data requests must be in hex without `0x` and in lowercase. Example:

  ```
  a614f803b6fd780986a42c78ec9c7f77e6ded13c
  ```

  All addresses in the responses will be in this format, too.
</Warning>

### Logs

```ts theme={"system"}
{
  // data requests
  address: string[],
  topic0: string[],
  topic1: string[],
  topic2: string[],
  topic3: string[],

  // related data retrieval
  transaction: boolean
}
```

* `address`: the set of addresses of contracts emitting the logs. Omit to subscribe to events from all contracts in the network.
* `topicN`: the set of values of topicN.

A log will be included in the response if it matches all the requests. An empty array matches no logs; omitted or `null` request matches any log.

With `transaction: true` all parent transactions will be included into the response.

### Transactions

<h4 id="general-transactions">
  General
</h4>

```ts theme={"system"}
{
  // data requests
  type: string[],

  // related data retrieval
  logs: boolean,
  internalTransactions: boolean
}
```

* `type`: the set of acceptable transaction types.

A transaction will be included in the response if it matches all the requests (just the `type` request in this case). An empty array matches no transactions; omitted or `null` request matches any transaction.

With `logs: true` all logs emitted by the transactions will be included into the response. With `internalTransactions: true` all the internal transactions induced by the selected transactions will be included into the response.

<h4 id="transfer-transactions">
  "transfer"
</h4>

```ts theme={"system"}
{
  // data requests
  owner: string[],
  to: string[],

  // related data retrieval
  logs: boolean,
  internalTransactions: boolean
}
```

* `owner`: the set of owner addresses for which the transfer transactions should be retrieved.
* `to`: the set of destination addresses.

A transaction will be included in the response if it matches all the requests. An empty array matches no transactions; omitted or `null` request matches any transaction.

With `logs: true` all logs emitted by the transactions will be included into the response. With `internalTransactions: true` all the internal transactions induced by the selected transactions will be included into the response.

<h4 id="transfer-asset-transactions">
  "transfer asset"
</h4>

```ts theme={"system"}
{
  // data requests
  owner: string[],
  to: string[],
  asset: string[],

  // related data retrieval
  logs: boolean,
  internalTransactions: boolean
}
```

* `owner`: the set of owner addresses for which the transfer transactions should be retrieved.
* `to`: the set of destination addresses.
* `asset`: the set of asset contract addresses.

A transaction will be included in the response if it matches all the requests. An empty array matches no transactions; omitted or `null` request matches any transaction.

With `logs: true` all logs emitted by the transactions will be included into the response. With `internalTransactions: true` all the internal transactions induced by the selected transactions will be included into the response.

<h4 id="trigger-smart-contract-transactions">
  "trigger smart contract"
</h4>

```ts theme={"system"}
{
  // data requests
  owner: string[],
  contract: string[],
  sighash: string[],

  // related data retrieval
  logs: boolean,
  internalTransactions: boolean
}
```

* `owner`: the set of addresses of call owners.
* `contract`: the set of addresses of contracts being called.
* `sighash`: the set of 4-byte signature hashes of the called functions, hex-encoded without a `0x` prefix.

A transaction will be included in the response if it matches all the requests. An empty array matches no transactions; omitted or `null` request matches any transaction.

With `logs: true` all logs emitted by the transactions will be included into the response. With `internalTransactions: true` all the internal transactions induced by the selected transactions will be included into the response.

### Internal transactions

```ts theme={"system"}
{
  // data requests
  caller: string[],
  transferTo: string[],

  // related data retrieval
  transaction: boolean
}
```

* `caller`: the set of addresses of caller contracts.
* `transferTo`: the set of addresses of receivers of TRX or TRC10 tokens.

A transaction will be included in the response if it matches all the requests. An empty array matches no transactions; omitted or `null` request matches any transaction.

With `transaction: true` all parent transactions for the selected internal transactions will be included into the response.

## Data fields selector

A selector of fields for the returned data items. Its structure is as follows:

```
{
  block:               // field selector for blocks
  log:                 // field selector for logs
  transaction:         // field selector for transactions
  internalTransaction: // field selector for internal transactions
}
```

The `transaction` field selector is common for [all transaction types](#transactions) except for the internal transactions.

A valid field selector of any given type is a JSON that has a subset of that type's fields as keys and `true` as values, e.g. `{"hash": true, "timestamp": true}`. Fields marked *always present* below are returned regardless of the selector.

### Block fields

`number`, `hash` and `parentHash` are always present. The selectable fields are:

```
{
  timestamp
  txTrieRoot
  version
  witnessAddress
  witnessSignature
}
```

### Log fields

`logIndex` and `transactionIndex` are always present. The selectable fields are:

```
{
  address
  data
  topics
}
```

### Transaction fields

`transactionIndex` is always present. The selectable fields are:

```
{
  hash
  ret
  signature
  type
  parameter
  permissionId
  refBlockBytes
  refBlockHash
  feeLimit
  expiration
  timestamp
  rawDataHex
  fee
  contractResult
  contractAddress
  resMessage
  withdrawAmount
  unfreezeAmount
  withdrawExpireAmount
  cancelUnfreezeV2Amount
  result
  energyFee
  energyUsage
  energyUsageTotal
  netUsage
  netFee
  originEnergyUsage
  energyPenaltyTotal
}
```

### Internal transaction fields

`transactionIndex` and `internalTransactionIndex` are always present. The selectable fields are:

```
{
  hash
  callerAddress
  transferToAddress
  callValueInfo
  note
  rejected
  extra
}
```
