Skip to main content

What are webhooks?

Webhooks are HTTP callbacks that M2M sends to your server when events occur. Instead of polling the API for updates, you receive instant notifications when:
  • A magic link is created
  • A user opens a magic link
  • M2M needs additional user data
  • A money transfer operation is created
  • A money transfer operation is cancelled

Configuration

Configure your webhook URL in the Partner Portal:
  1. Navigate to Settings > Webhooks
  2. Enter your webhook endpoint URL (must be HTTPS)
  3. Save your configuration
  4. Copy your webhook secret for signature verification
Your webhook endpoint must use HTTPS. HTTP endpoints are not supported for security reasons.
You can override the default webhook URL for specific links by providing a callbackUrl when creating the link:
{
  "referenceId": "user_123",
  "callbackUrl": "https://api.yourcompany.com/webhooks/m2m/special"
}

Webhook format

All webhooks are sent as HTTP POST requests with a JSON body:
{
  "event": "link.opened",
  "timestamp": "2026-01-26T14:30:00.000Z",
  "data": {
    // Event-specific payload
  }
}

Headers

Every webhook includes these headers:
HeaderDescription
Content-TypeAlways application/json
X-M2M-EventEvent type (e.g., link.opened)
X-M2M-TimestampUnix timestamp (seconds)
X-M2M-SignatureHMAC-SHA256 signature for verification
Always verify the X-M2M-Signature header before processing webhooks. See Webhook Security for implementation details.

Delivery guarantees

M2M implements reliable webhook delivery with automatic retries:

Retry schedule

If your endpoint returns a non-2xx status code or times out, M2M retries with exponential backoff:
AttemptDelay after failure
1Immediate
21 minute
35 minutes
430 minutes
52 hours
After 5 failed attempts, the webhook is marked as failed. You can replay failed webhooks from the Partner Portal.

Timeout

Your endpoint must respond within 30 seconds. If processing takes longer, return a 200 OK immediately and process the webhook asynchronously.

Success criteria

A webhook is considered delivered when your endpoint returns:
  • HTTP status code 200-299
  • Within 30 seconds

Best practices

Return a 200 OK response as soon as you receive the webhook. Process the payload asynchronously if needed.
app.post('/webhooks/m2m', async (req, res) => {
  // Verify signature first
  if (!verifySignature(req)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Acknowledge immediately
  res.status(200).send('OK');
  
  // Process asynchronously
  processWebhookAsync(req.body);
});
Webhooks may be delivered more than once. Use the event data to ensure you don’t process the same event twice.
async function processWebhook(event) {
  const eventKey = `${event.event}-${event.data.linkId}-${event.timestamp}`;
  
  if (await cache.has(eventKey)) {
    console.log('Duplicate webhook, skipping');
    return;
  }
  
  await cache.set(eventKey, true, { ttl: 86400 });
  // Process the event...
}
Always verify the X-M2M-Signature header to ensure the webhook came from M2M. See Webhook Security.
New event types may be added. Return 200 OK for unknown events instead of an error.
switch (event.event) {
  case 'link.created':
    handleLinkCreated(event.data);
    break;
  case 'link.opened':
    handleLinkOpened(event.data);
    break;
  case 'user.data_request':
    handleDataRequest(event.data);
    break;
  case 'operation.created':
    handleOperationCreated(event.data);
    break;
  case 'operation.cancelled':
    handleOperationCancelled(event.data);
    break;
  default:
    console.log(`Unknown event type: ${event.event}`);
    // Still return 200 OK
}
Store webhook payloads for debugging and audit purposes. This helps troubleshoot issues and track user journeys.
Use the Partner Portal to monitor webhook delivery success rates. Set up alerts for repeated failures.

Testing webhooks

Sandbox environment

In the sandbox environment, webhooks work exactly like production. Use a tool like ngrok to expose your local development server:
ngrok http 3000
Then configure the ngrok URL as your webhook endpoint in the Partner Portal.

Manual testing

  1. Create a magic link in sandbox
  2. Check your webhook endpoint for the link.created event
  3. Open the link in your browser
  4. Check your webhook endpoint for the link.opened event
  5. If you didn’t provide full user data, you’ll receive a user.data_request event
  6. Complete a money transfer in the widget to receive an operation.created event
  7. Cancel an operation from the widget to receive an operation.cancelled event

Troubleshooting

  • Verify your endpoint URL is correct and uses HTTPS
  • Check that your server is publicly accessible
  • Review firewall rules that might block M2M’s IP addresses
  • Check the Partner Portal for delivery errors
  • Ensure you’re using the raw request body (before JSON parsing)
  • Verify you’re using the correct webhook secret
  • Check that you haven’t modified the payload before verification
  • Check your endpoint’s response time
  • Ensure you’re returning 200 OK promptly
  • Review the retry schedule - delayed webhooks may be retries

Next steps

Webhook Events

See all event types and their payloads.

Webhook Security

Implement signature verification.