Webhooks
Receive real-time notifications when emails are sent or received. Webhooks are delivered via HTTPS POST with cryptographic signature verification.
Event Types
| Event | Trigger | Use Case |
|---|---|---|
email.sent.received | Email sent through SMTP | Verify your app sends correct emails |
email.inbox.received | Email received to inbox | React to incoming verification emails |
Webhook Headers
| Header | Description |
|---|---|
X-Webhook-Signature | HMAC-SHA256 signature for verification |
X-Webhook-Timestamp | ISO 8601 timestamp of event |
X-Webhook-ID | Unique delivery ID (UUID) |
User-Agent | SigninID-Webhook/1.0 |
Payload Fields
| Field | Type | Description |
|---|---|---|
email_id | string | Unique email ID |
server_id | string | Server ID |
from_address | string | Sender email address |
from_name | string | null | Sender display name |
to_addresses | string[] | Recipient addresses |
cc_addresses | string[] | null | CC addresses |
bcc_addresses | string[] | null | BCC addresses |
subject | string | null | Email subject |
sent_at | string | ISO 8601 timestamp |
message_id | string | null | Message ID header |
has_attachments | boolean | Has attachments |
attachment_count | number | Number of attachments |
spam_score | number | null | Spam score (0-10+) |
spam_verdict | string | PASS / SOFT_FAIL / FAIL |
detected_otp | string | null | Detected OTP code |
html_body | string | null | HTML content |
text_body | string | null | Plain text content |
Signature Verification
import crypto from 'crypto';
function verifyWebhookSignature(
payload: string, // Raw request body
signature: string, // X-Webhook-Signature header
secret: string // Your webhook secret
): boolean {
const expected = 'sha256=' +
crypto.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Example Payloads
The detected_otp field is automatically populated when a verification code is found.
Webhook Handler Example (Express.js)
// Express.js webhook handler
app.post('/webhook/signinid', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = req.body.toString();
if (!verifyWebhookSignature(payload, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(payload);
if (event.event_type === 'email.sent.received') {
const { detected_otp, to_addresses, subject } = event.data;
if (detected_otp) {
console.log(`OTP ${detected_otp} sent to ${to_addresses[0]}`);
// Store OTP for test verification
}
}
res.status(200).send('OK');
});