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

# Event Types Reference

> Complete list of Off the Hook event kinds, their payload fields, and availability status. Use these kind strings in your subscription's events array.

Event kind strings in Off the Hook follow the pattern `<scope>.<entity>.<status>`. Because `chainId` and asset information are always present in the payload `data` object, one handler covers every chain and every asset type — you never need separate subscriptions for TRX versus TRC-20 tokens, or for mainnet versus testnet. Add one or more of the kind strings below to the `events` array when creating or updating a subscription.

## Available events

### `wallet.transfer.broadcasted`

Fired when a TRX or TRC-20 transfer is confirmed in a new block. This is the primary event for monitoring wallet activity.

**TRC-20 token transfer**

```json theme={null}
{
  "id": "evt_8xN9kP2QbA...",
  "kind": "wallet.transfer.broadcasted",
  "date": "2026-05-08T12:34:56Z",
  "data": {
    "chainId": "tron:mainnet",
    "blockNumber": 78912345,
    "blockHash": "00000000...",
    "blockTimestamp": 1730000000000,
    "txId": "abc123...",
    "logIndex": 0,
    "from": "TLsV52sRDL79HXGGm9yzwKibb6BeruhUzy",
    "to": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "amount": "1500000000",
    "asset": {
      "type": "fungible",
      "contract": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
      "symbol": "USDT",
      "decimals": 6
    },
    "matchedAddresses": [
      { "chainId": "tron:mainnet", "address": "TLsV52sRDL79HXGGm9yzwKibb6BeruhUzy", "role": "from" }
    ]
  }
}
```

**Native TRX transfer**

For native TRX, `asset.type` is `"native"`, `contract` is `null`, and `logIndex` is `-1`. The `-1` value is intentional — it distinguishes a native transfer from the first TRC-20 log in the same transaction, which uses index `0`.

```json theme={null}
{
  "id": "evt_...",
  "kind": "wallet.transfer.broadcasted",
  "date": "2026-05-08T12:34:56Z",
  "data": {
    "chainId": "tron:mainnet",
    "blockNumber": 78912345,
    "blockHash": "00000000...",
    "blockTimestamp": 1730000000000,
    "txId": "xyz789...",
    "logIndex": -1,
    "from": "TLsV52sRDL79HXGGm9yzwKibb6BeruhUzy",
    "to": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "amount": "1000000",
    "asset": {
      "type": "native",
      "contract": null,
      "symbol": "TRX",
      "decimals": 6
    },
    "matchedAddresses": [
      { "chainId": "tron:mainnet", "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "role": "to" }
    ]
  }
}
```

<Note>
  When Off the Hook encounters a TRC-20 contract it has no metadata for, `asset.symbol` and `asset.decimals` are both `null`. Your code should handle these null values and display the raw `amount` string rather than attempting to format it.
</Note>

**Payload field reference**

| Field                   | Type            | Description                                                                             |
| ----------------------- | --------------- | --------------------------------------------------------------------------------------- |
| `id`                    | string          | Unique event identifier, prefixed `evt_`                                                |
| `kind`                  | string          | Always `wallet.transfer.broadcasted` for this event                                     |
| `date`                  | string          | ISO 8601 timestamp when the event was created                                           |
| `data.chainId`          | string          | CAIP-2 chain identifier (e.g. `tron:mainnet`)                                           |
| `data.blockNumber`      | integer         | Block height where the transfer was confirmed                                           |
| `data.blockHash`        | string          | Hash of the confirming block                                                            |
| `data.blockTimestamp`   | integer         | Block timestamp in milliseconds since Unix epoch                                        |
| `data.txId`             | string          | Transaction ID on the TRON network                                                      |
| `data.logIndex`         | integer         | Log index within the transaction; `-1` for native TRX transfers                         |
| `data.from`             | string          | Sender address (TRON base58check)                                                       |
| `data.to`               | string          | Recipient address (TRON base58check)                                                    |
| `data.amount`           | string          | Transfer amount as a raw integer string, in the asset's smallest unit                   |
| `data.asset.type`       | string          | `"native"` for TRX, `"fungible"` for TRC-20 tokens                                      |
| `data.asset.contract`   | string \| null  | TRC-20 contract address; `null` for native TRX                                          |
| `data.asset.symbol`     | string \| null  | Token symbol (e.g. `"USDT"`); `null` if contract is unknown                             |
| `data.asset.decimals`   | integer \| null | Decimal places for the asset; `null` if contract is unknown                             |
| `data.matchedAddresses` | array           | Which of your watched addresses triggered the event and their role (`"from"` or `"to"`) |

***

### `service.ping`

A system event fired by the `POST /v1/subscriptions/:id/test` endpoint. Use it to verify that your endpoint is reachable and returning `2xx` responses before you start monitoring live chain activity.

```json theme={null}
{
  "id": "evt_...",
  "kind": "service.ping",
  "date": "2026-05-08T12:00:00Z",
  "data": {}
}
```

## Planned events

These event kinds are not yet available. Do not include them in your `events` array — the API returns an `unsupported_event` error if you do.

<AccordionGroup>
  <Accordion title="wallet.transfer.confirmed">
    Fired after a transfer receives enough block confirmations to be considered final. Requires polling for confirmation depth — planned for a future release.
  </Accordion>

  <Accordion title="wallet.transfer.failed">
    Fired when a transfer transaction is detected as reverted or failed. Requires revert detection logic — planned for a future release.
  </Accordion>

  <Accordion title="wallet.contract_call.broadcasted">
    Fired when a smart contract call appears in a new block. Planned for a future release.
  </Accordion>

  <Accordion title="wallet.contract_call.confirmed">
    Fired after a contract call reaches confirmation depth. Planned for a future release.
  </Accordion>

  <Accordion title="wallet.contract_call.failed">
    Fired when a contract call is reverted. Planned for a future release.
  </Accordion>

  <Accordion title="wallet.balance.crossed_threshold">
    Fired when a wallet balance crosses a configured threshold in either direction. Planned for a future release.
  </Accordion>
</AccordionGroup>
