Skip to main content
Every webhook delivery from Off the Hook is a Standard Webhooks-compliant HTTP POST to your destination URL. The body is a JSON envelope with a consistent shape across all event types: a unique event ID, a kind string that identifies what happened, a timestamp, and a data object containing the chain-specific transfer details. Your endpoint can use these fields to identify the event, verify it hasn’t been processed before, and extract the transfer information you need.

Payload structure

Envelope fields

string
required
Unique event identifier, prefixed evt_. This ID is stable across retries — if Off the Hook retries a failed delivery, the same id appears in every attempt. Use it as your idempotency key to avoid processing the same transfer twice.
string
required
The event type string, such as "wallet.transfer.broadcasted". Your subscription only receives events whose kinds appear in its events array. See event types for all supported values.
string
required
ISO 8601 timestamp of when the event was generated.

Transfer data fields

string
required
CAIP-2 chain identifier for the network where the transfer occurred, such as "tron:mainnet". See supported networks.
number
required
The block number that included this transfer.
string
required
The hash of the block that included this transfer.
number
required
Unix timestamp of the block in milliseconds.
string
required
The TRON transaction ID.
number
required
Position of this transfer within the block. For TRC-20 tokens this is the index of the Transfer log event (0-based). For native TRX transfers this is always -1 — a deliberate sentinel that avoids colliding with the first TRC-20 log in the same transaction.
string
required
Sender address in canonical TRON base58check format (starts with T).
string
required
Recipient address in canonical TRON base58check format.
string
required
Raw integer transfer amount as a string. Divide by 10^asset.decimals to get the human-readable value. For example, "1500000000" with decimals: 6 is 1,500 USDT.
object
required
Describes the transferred token.
object[]
required
The addresses from your subscription’s filter list that caused this event to fire. Each entry includes the chain, the address, and the role it played in the transfer: "from" if the address sent the funds, or "to" if it received them. A single transfer can match the same address in both roles if your filter includes both sender and recipient.

Deduplication

Off the Hook retries deliveries on 5xx, 408, 429, and network errors using a backoff schedule of 200ms, 1s, 5s, 1min, 5min, 30min, and 2h. Every attempt — original and retries — carries the same webhook-id header, which matches the id field in the payload body. To avoid processing the same transfer twice, record the webhook-id of every delivery you successfully handle and skip any delivery whose ID you’ve already seen.

Delivery headers

Each POST request Off the Hook sends includes the following headers: During a secret rotation grace window, the webhook-signature header contains multiple v1, values separated by spaces — one for each active secret. A valid signature from any of them means the delivery is authentic.

Next steps