Docs / Quickstart
Quickstart
From signup to your first confirmed-deposit webhook in about 5 minutes. Signup is free, takes 30 seconds, and needs no credit card.
1. Create an account and an API key
- Sign up at tronhooks.com/app (email + password).
- In API keys, create a key (
tw_live_…, mainnet). 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.
How to test
tronhooks runs against TRON mainnet — you can verify everything end-to-end without risking funds:
- TEST button (no chain activity) — in the console's watch form, press Send test: a signed sample notification goes to your webhook URL or Telegram immediately. Perfect for verifying your endpoint, signature check and parsing.
- Watch a busy address (instant real events) — add a watch on any active mainnet address and real confirmed events start flowing within seconds. To find one, open Tronscan's USDT transfer list and pick an address that appears again and again — exchange hot wallets are ideal. Delete the watch when you're done.
- Full loop with your own address — watch your own address with direction
both, then send yourself 1 TRX (fees are a few cents). One block later (~3 s after finality) the signed webhook / Telegram message arrives with the matching Tronscan link.
All keys are tw_live_… and all data is mainnet. A testnet (Nile) environment is not currently offered — testnet-network requests return testnet_unsupported. It's on the roadmap; if you need it, tell us: ops@tronhooks.com.
Watching outgoing transfers
By default a watch fires on incoming transfers (deposits). Set direction to outgoing (alert when the address sends) or both:
-d '{ "address": "T...", "asset_filter": "USDT", "direction": "both", "webhook_url": "..." }'
The payload's direction field tells you which side matched; Telegram messages show 📤 sent / ✅ received accordingly.
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 consoleReady? Free tier, 30-second signup, no credit card.
Create your account →