Flexible Routing
Exact recipient matches, wildcard patterns (dev-*@intent.ngo), or global catch-all routing.
HMAC Webhooks
Transform raw MIME into rich JSON payloads signed with constant-time HMAC-SHA256 headers.
Anti-SSRF Protection
Strict egress DNS resolution blocks loopback, private ranges, and cloud metadata IPs from webhook targets.
DKIM Forwarding
Outbound forwards are cryptographically signed with the 2048-bit RSA DKIM key for intent.ngo.
Interactive Route Matcher
Test how an incoming recipient address resolves against active rules.
dev-ops@intent.ngo.Click "Test" to evaluate route
REST API Reference
Base URL: https://routing.intent.ngo. All authenticated endpoints require Authorization: Bearer <API_KEY>.
Retrieve all configured routing rules for the domain.
curl -H "Authorization: Bearer rt_live_..." https://routing.intent.ngo/api/v1/routes
Create a new routing rule (forward, webhook, store, or drop).
curl -X POST https://routing.intent.ngo/api/v1/routes \
-H "Authorization: Bearer rt_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Dev Webhook Relay",
"domain": "intent.ngo",
"match_type": "prefix",
"match_pattern": "dev-*@intent.ngo",
"action": "webhook",
"webhook_url": "https://api.myservice.com/inbound-mail",
"priority": 10
}'
Simulate which route matches a prospective incoming recipient address.
curl -X POST https://routing.intent.ngo/api/v1/routes/test \
-H "Authorization: Bearer rt_live_..." \
-H "Content-Type: application/json" \
-d '{"recipient": "support@intent.ngo"}'
Query real-time delivery audit trails, webhook latencies, and dispatch statuses.
curl -H "Authorization: Bearer rt_live_..." https://routing.intent.ngo/api/v1/logs?limit=20
Verifying Webhook Signatures
Every webhook request dispatched by Intent-Routing contains the X-Routing-Signature header:
t=<timestamp>,v1=<hmac_sha256_hex>.
Verify it in constant time to thwart spoofing and replay attacks.
// Node.js Verification Example
const crypto = require('crypto');
function verifyWebhook(payloadRawString, signatureHeader, secret) {
const parts = Object.fromEntries(signatureHeader.split(',').map(kv => kv.split('=')));
const timestamp = parts.t;
const signature = parts.v1;
// Reject replays older than 5 minutes
if (Math.abs(Math.floor(Date.now() / 1000) - parseInt(timestamp, 10)) > 300) {
throw new Error('Webhook timestamp expired');
}
const expected = crypto.createHmac('sha256', secret)
.update(`${timestamp}.${payloadRawString}`)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex'));
}