All systems operational
Live FX data
Updated 2m ago
API Reference

Webhooks

Get notified in real-time when exchange rates change.

Webhooks are available on Pro and Enterprise plans.

Overview

Webhooks deliver HTTP POST requests to your endpoint whenever rates change beyond a configured threshold. Use them to update prices in real-time, trigger repricing logic, or keep your database in sync — without polling.

Setting Up a Webhook

1

Register your endpoint

Go to Dashboard › Webhooks › Add Endpoint and fill in the fields below.

FieldDetails
Endpoint URLMust be HTTPS. No localhost in production.
CurrenciesSelect which pairs to monitor (e.g. USD/JPY, EUR/GBP).
Threshold %Trigger when rate changes by this %. Minimum: 0.1%.
2

Verify your endpoint

When registered, xchangr8 sends a one-time verification POST. Your endpoint must respond with HTTP 200 and echo back the challenge.

Incoming verification payload

JSON
{
  "type": "webhook.verify",
  "challenge": "abc123xyz"
}

Your endpoint must respond with

JSON
{ "challenge": "abc123xyz" }
3

Handle events

Once verified, your endpoint will receive rate.changed events whenever a monitored pair crosses your threshold.

Webhook Payload Shape

JSON
{
  "id": "evt_01HZXXXX",
  "type": "rate.changed",
  "timestamp": 1749340800,
  "data": {
    "pair": "USD/JPY",
    "rate_before": 149.12,
    "rate_after": 150.88,
    "change_pct": 1.18,
    "threshold_pct": 0.5
  }
}

Event Types

EventTrigger
rate.changed Rate moved beyond your configured threshold
rate.spike Rate moved >2% in 1 hour (always sent, regardless of threshold)
webhook.verify Endpoint verification challenge
webhook.test Manual test triggered from dashboard

Security — Verifying Signatures

Every webhook request includes an X-XC8-Signature header. Always verify it before processing the payload to prevent spoofed requests.

JavaScript (Node.js)
const crypto = require('crypto')

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex')
  return `sha256=${expected}` === signature
}

app.post('/webhooks/xc8', (req, res) => {
  const sig = req.headers['x-xc8-signature']
  if (!verifyWebhook(req.rawBody, sig, process.env.XC8_WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature')
  }
  // Process event
  res.status(200).send('OK')
})

Retry Policy

Failed deliveries (non-2xx response or timeout) are retried automatically with exponential backoff.

After 5 consecutive failures: the webhook is automatically disabled and an email is sent to the account owner. Re-enable it from Dashboard › Webhooks after fixing your endpoint.

Best Practices