Webhooks

Receive real-time notifications when emails are sent or received. Webhooks are delivered via HTTPS POST with cryptographic signature verification.

Event Types

EventTriggerUse Case
email.sent.receivedEmail sent through SMTPVerify your app sends correct emails
email.inbox.receivedEmail received to inboxReact to incoming verification emails

Webhook Headers

HeaderDescription
X-Webhook-SignatureHMAC-SHA256 signature for verification
X-Webhook-TimestampISO 8601 timestamp of event
X-Webhook-IDUnique delivery ID (UUID)
User-AgentSigninID-Webhook/1.0

Payload Fields

FieldTypeDescription
email_idstringUnique email ID
server_idstringServer ID
from_addressstringSender email address
from_namestring | nullSender display name
to_addressesstring[]Recipient addresses
cc_addressesstring[] | nullCC addresses
bcc_addressesstring[] | nullBCC addresses
subjectstring | nullEmail subject
sent_atstringISO 8601 timestamp
message_idstring | nullMessage ID header
has_attachmentsbooleanHas attachments
attachment_countnumberNumber of attachments
spam_scorenumber | nullSpam score (0-10+)
spam_verdictstringPASS / SOFT_FAIL / FAIL
detected_otpstring | nullDetected OTP code
html_bodystring | nullHTML content
text_bodystring | nullPlain 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.

{
  "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "event_type": "email.sent.received",
  "timestamp": "2024-01-15T10:30:00.123Z",
  "data": {
    "email_id": "550e8400-e29b-41d4-a716-446655440000",
    "server_id": "123e4567-e89b-12d3-a456-426614174000",
    "from_address": "noreply@yourapp.com",
    "from_name": "Your App",
    "to_addresses": ["user@test.com"],
    "cc_addresses": null,
    "bcc_addresses": null,
    "subject": "Verify your email address",
    "sent_at": "2024-01-15T10:30:00Z",
    "message_id": "",
    "has_attachments": false,
    "attachment_count": 0,
    "spam_score": 0.1,
    "spam_verdict": "PASS",
    "detected_otp": "847291",
    "html_body": "

Your verification code is: 847291

", "text_body": "Your verification code is: 847291" } }

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');
});