Quick Start Guide
Get XRNotify integrated in your application in under 10 minutes. This guide walks you through creating an API key, registering a webhook, verifying signatures, and testing your integration.
Get your API key
Every request to the XRNotify API must be authenticated with an API key. Navigate to your dashboard to create one.
- Open your Dashboard
- Go to Settings → API Keys
- Click Create new key
- Copy and store the key securely — it won't be shown again
Your key will look like this:
xrn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxTip: Use test keys (xrn_test_...) during development. Test keys behave identically but only deliver test events — no real XRPL data.
Register a webhook
A webhook is an HTTPS endpoint in your application that XRNotify will POST events to. Register it using the API or the dashboard.
curl -X POST https://api.xrnotify.io/v1/webhooks \
-H "X-XRNotify-Key: xrn_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/xrpl",
"event_types": ["payment.xrp", "nft.minted"],
"account_filters": ["rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe"]
}'The account_filters field is optional — omit it to receive events for all XRPL accounts. The response includes a secret field that you'll use to verify incoming requests.
Handle incoming webhooks
When XRNotify delivers an event to your endpoint, it signs the raw request body using HMAC-SHA256 and includes the signature in the X-XRNotify-Signature header. Always verify this before processing.
const express = require('express');
const crypto = require('crypto');
const app = express();
app.post('/webhooks/xrpl', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-xrnotify-signature'];
const expected = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (signature !== `sha256=${expected}`) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
console.log('Event received:', event.event_type);
// Handle your event types
switch (event.event_type) {
case 'payment.xrp':
// handle XRP payment
break;
case 'nft.minted':
// handle NFT mint
break;
}
res.status(200).send('OK');
});
app.listen(3000);Important: Use express.raw() — not express.json() — so you can verify the raw bytes. Parsing JSON before verification will break signature checks.
Test your integration
Send a test event to your webhook without waiting for a real XRPL transaction:
curl -X POST https://api.xrnotify.io/v1/webhooks/wh_your_id_here/test \
-H "X-XRNotify-Key: xrn_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"event_type": "payment.xrp"}'Alternatively, trigger a real transaction on the XRPL Testnet using a funded wallet. XRNotify will detect and deliver the event within seconds.
Event payload structure
Every event delivered to your webhook follows this structure. The payload field varies by event type.
{
"event_id": "xrpl:89547832:A4B2F1E3C9D4:payment.xrp",
"event_type": "payment.xrp",
"ledger_index": 89547832,
"timestamp": "2024-01-15T10:23:45Z",
"network": "mainnet",
"webhook_id": "wh_abc123",
"payload": {
"sender": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
"receiver": "rN7n3473SaZBCG4dFL83w7PB2bBdDiAkzN",
"amount": "1000000",
"fee": "12",
"delivered_amount": "1000000",
"destination_tag": 12345,
"tx_hash": "A4B2F1E3C9D4..."
}
}amounts
XRP amounts are in drops (1 XRP = 1,000,000 drops)
idempotency
Use event_id to deduplicate in your database