Docs / Quickstart
Quickstart
From signup to your first confirmed-deposit webhook in about 5 minutes.
1. Create an account and an API key
- Sign up at tronhooks.com/app (email + password).
- In API keys, create a key. Prefixes are network-bound:
tw_test_…works against Nile testnet deployments,tw_live_…against mainnet (this instance). The key is shown once — store it now.
2. Watch an address
curl -X POST https://tronhooks.com/v1/watches \
-H "Authorization: Bearer tw_live_..." \
-H "Content-Type: application/json" \
-d '{
"address": "TYourAddress...",
"asset_filter": "USDT",
"webhook_url": "https://your-server.example/tron-hook"
}'
The 201 response contains the watch and — exactly once — its signing secret (whsec_…). Store it next to the endpoint that will receive the webhooks.
⚠️ The secret is shown only once. It is stored encrypted on our side and can never be retrieved again — if you lose it, delete the watch and create a new one.
Activation: a new watch becomes effective within ~3 seconds (one scan cycle). Transfers that happened before activation are never matched retroactively.
Or with the TypeScript SDK (npm i @tronhooks/sdk):
import { TronHooks } from '@tronhooks/sdk';
const th = new TronHooks('tw_live_...');
const watch = await th.watches.create({
address: 'TYourAddress...',
assetFilter: 'USDT', // USDT | TRX | ALL
webhookUrl: 'https://your-server.example/tron-hook',
});
// store watch.secret
3. Receive and verify the webhook
When a deposit is confirmed (solidity-node finality), we POST a JSON payload with an X-Signature header. Verify it against the raw request body:
import express from 'express';
import { constructEvent } from '@tronhooks/sdk';
const app = express();
app.post('/tron-hook', express.raw({ type: 'application/json' }), (req, res) => {
const event = constructEvent(req.body, req.header('x-signature'), process.env.WHSEC);
console.log(`${event.amount} ${event.asset} → ${event.to} (tx ${event.tx_id})`);
res.sendStatus(200); // any 2xx acknowledges delivery
});
You MUST verify against the raw request body — the exact bytes received, before any JSON parsing. Any re-serialization (JSON.stringify(req.body), framework body parsers, pretty-printing) changes byte order and will make verification fail. That's why the example uses express.raw(). Details and Python/no-SDK variants: Verifying webhooks.
4. Reconcile any time
curl https://tronhooks.com/v1/events?limit=10 \
-H "Authorization: Bearer tw_live_..."
GET /v1/events returns every event with its delivery status — your safety net if your receiver was down. Deliveries are at-least-once: dedupe on event_id.
No code? Telegram path
- Sign up at /app.
- Click Connect Telegram → open the link → press Start (works for groups too: add
@tronhooks_botand send/bind <code>). - Add an address with the → Telegram target. Done — confirmed deposits arrive as Telegram messages with a Tronscan link.
Troubleshooting: no webhook arriving?
- Your URL is unreachable — or rejected by our SSRF rules. The endpoint must be a publicly resolvable http(s) URL; private/reserved addresses (localhost, 10.x, 192.168.x, cloud-metadata IPs…) are refused at creation and at delivery time. Tunnels (or our webhook debugger) help during development.
- Signature verification fails on your side. Almost always the raw-body rule above — a body parser touched the bytes before your HMAC. Fix the middleware order, don't disable verification.
- Check the delivery log. Console → Events & delivery log → click the event: every attempt's HTTP status and error is recorded (retries run 1m/5m/30m/2h/6h, then dead-letter).
GET /v1/eventsshows the same via API.
Error responses you might hit along the way: error code table.
That's the whole integration. Free tier: 3 watched addresses, no card required.
Open the console