Skip to main content

What are Webhooks?

Webhooks allow you to receive real-time notifications when events occur in your Transmit account. Subscribe to specific event types and receive HTTP POST requests to your endpoint whenever those events happen.

Available Event Types

Email Events

email.sent

Triggered when an email has been successfully submitted to the email provider for delivery.Example Payload:
{
  "id": "evt_email123_sent",
  "type": "email.sent",
  "created_at": 1704894225000,
  "data": {
    "email_id": "email_abc123",
    "from": "[email protected]",
    "to": ["[email protected]"],
    "subject": "Welcome to Transmit",
    "sent_at": 1704894225000
  }
}
Triggered when an email has been successfully delivered to the recipient’s mail server.Example Payload:
{
  "id": "evt_email123_delivered",
  "type": "email.delivered",
  "created_at": 1704894230000,
  "data": {
    "email_id": "email_abc123",
    "from": "[email protected]",
    "to": ["[email protected]"],
    "subject": "Welcome to Transmit",
    "delivered_at": 1704894230000,
    "provider": "aws_ses",
    "provider_message_id": "0000014a-f4d4-4f4f-8f4f-4f4f4f4f4f4f"
  }
}
Triggered when a recipient opens an email (tracking pixels enabled).Example Payload:
{
  "id": "evt_email123_opened",
  "type": "email.opened",
  "created_at": 1704894245000,
  "data": {
    "email_id": "email_abc123",
    "to": "[email protected]",
    "opened_at": 1704894245000,
    "user_agent": "Mozilla/5.0...",
    "ip_address": "192.0.2.1"
  }
}
Triggered when a recipient clicks a link in an email (link tracking enabled).Example Payload:
{
  "id": "evt_email123_clicked",
  "type": "email.clicked",
  "created_at": 1704894250000,
  "data": {
    "email_id": "email_abc123",
    "to": "[email protected]",
    "clicked_at": 1704894250000,
    "link": "https://example.com/welcome",
    "user_agent": "Mozilla/5.0...",
    "ip_address": "192.0.2.1"
  }
}
Triggered when an email bounces (hard or soft bounce).Example Payload:
{
  "id": "evt_email123_bounced",
  "type": "email.bounced",
  "created_at": 1704894260000,
  "data": {
    "email_id": "email_abc123",
    "to": "[email protected]",
    "bounced_at": 1704894260000,
    "bounce_type": "hard",
    "bounce_reason": "mailbox_full",
    "diagnostic_code": "550 5.1.1 User unknown"
  }
}
Triggered when a recipient marks an email as spam.Example Payload:
{
  "id": "evt_email123_complained",
  "type": "email.complained",
  "created_at": 1704894270000,
  "data": {
    "email_id": "email_abc123",
    "to": "[email protected]",
    "complained_at": 1704894270000,
    "feedback_type": "abuse"
  }
}

Domain Events

Triggered when a new domain is added to your account.Example Payload:
{
  "id": "evt_domain123_added",
  "type": "domain.added",
  "created_at": 1704894280000,
  "data": {
    "domain_id": "domain_abc123",
    "domain": "example.com",
    "apex_domain": "example.com",
    "nickname": "Production Domain",
    "status": "pending"
  }
}
Triggered when a domain has been successfully verified.Example Payload:
{
  "id": "evt_domain123_verified",
  "type": "domain.verified",
  "created_at": 1704894290000,
  "data": {
    "domain_id": "domain_abc123",
    "domain": "example.com",
    "verified_at": 1704894290000
  }
}
Triggered when domain verification fails.Example Payload:
{
  "id": "evt_domain123_failed",
  "type": "domain.failed_verification",
  "created_at": 1704894300000,
  "data": {
    "domain_id": "domain_abc123",
    "domain": "example.com",
    "reason": "DNS records not found"
  }
}
Triggered when a domain is removed from your account.Example Payload:
{
  "id": "evt_domain123_removed",
  "type": "domain.removed",
  "created_at": 1704894310000,
  "data": {
    "domain_id": "domain_abc123",
    "domain": "example.com"
  }
}

Contact Events

Triggered when a new contact is created.Example Payload:
{
  "id": "evt_contact123_created",
  "type": "contact.created",
  "created_at": 1704894320000,
  "data": {
    "contact_id": "contact_abc123",
    "email": "[email protected]",
    "phone_number": "+1234567890",
    "first_name": "John",
    "last_name": "Doe"
  }
}
Triggered when a contact is updated.Example Payload:
{
  "id": "evt_contact123_updated",
  "type": "contact.updated",
  "created_at": 1704894330000,
  "data": {
    "contact_id": "contact_abc123",
    "email": "[email protected]",
    "first_name": "Jane"
  }
}
Triggered when a contact is deleted.Example Payload:
{
  "id": "evt_contact123_deleted",
  "type": "contact.deleted",
  "created_at": 1704894340000,
  "data": {
    "contact_id": "contact_abc123",
    "email": "[email protected]"
  }
}
Triggered when a contact opts in to receive emails.Example Payload:
{
  "id": "evt_contact123_subscribed",
  "type": "contact.subscribed",
  "created_at": 1704894350000,
  "data": {
    "contact_id": "contact_abc123",
    "email": "[email protected]",
    "channel": "email"
  }
}
Triggered when a contact unsubscribes from emails.Example Payload:
{
  "id": "evt_contact123_unsubscribed",
  "type": "contact.unsubscribed",
  "created_at": 1704894360000,
  "data": {
    "contact_id": "contact_abc123",
    "email": "[email protected]",
    "channel": "email",
    "reason": "user_request"
  }
}

Suppression Events

Triggered when an email or phone number is added to the suppression list.Example Payload:
{
  "id": "evt_suppression123_added",
  "type": "suppression.added",
  "created_at": 1704894370000,
  "data": {
    "identifier": "[email protected]",
    "identifier_type": "email",
    "suppression_type": "hard_bounce",
    "reason": "mailbox_full"
  }
}
Triggered when an email or phone number is removed from the suppression list.Example Payload:
{
  "id": "evt_suppression123_removed",
  "type": "suppression.removed",
  "created_at": 1704894380000,
  "data": {
    "identifier": "[email protected]",
    "identifier_type": "email"
  }
}

SMS Events (Coming Soon)

Setting Up Webhooks

1

Create an Endpoint

Create an HTTPS endpoint on your server to receive webhook events
2

Add Webhook in Dashboard

Go to SettingsWebhooksAdd Webhook
3

Enter URL and Select Events

Enter your endpoint URL and choose which events to receive
4

Test Your Webhook

Use the test button to send a sample payload

Webhook Payload

Example webhook payload:
{
  "event": "email.delivered",
  "timestamp": "2025-01-10T14:23:45Z",
  "data": {
    "id": "email_abc123",
    "to": "[email protected]",
    "from": "[email protected]",
    "subject": "Welcome!",
    "status": "delivered",
    "deliveredAt": "2025-01-10T14:23:45Z"
  }
}

Handling Webhooks

import express from 'express';
import { Transmit } from 'transmitdev';

const app = express();
app.use(express.json());

app.post('/webhooks/transmit', async (req, res) => {
  const { event, data } = req.body;

  switch (event) {
    case 'email.delivered':
      console.log(`Email ${data.id} delivered to ${data.to}`);
      break;
    case 'email.bounced':
      console.log(`Email ${data.id} bounced: ${data.bounceReason}`);
      break;
    case 'email.opened':
      console.log(`Email ${data.id} opened by ${data.to}`);
      break;
  }

  res.status(200).send('OK');
});

app.listen(3000);

Verifying Webhooks

Transmit signs all webhook requests. Verify the signature to ensure authenticity:
import crypto from 'crypto';

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

app.post('/webhooks/transmit', (req, res) => {
  const signature = req.headers['x-transmit-signature'];
  const secret = process.env.TRANSMIT_WEBHOOK_SECRET;

  if (!verifyWebhookSignature(req.body, signature, secret)) {
    return res.status(401).send('Invalid signature');
  }

  // Process webhook...
  res.status(200).send('OK');
});

Retries

Transmit will retry failed webhooks:
  • Initial retry: after 1 minute
  • Second retry: after 5 minutes
  • Third retry: after 30 minutes
  • Final retry: after 2 hours
Your endpoint must return a 2xx status code within 30 seconds to be considered successful.

Best Practices

Return 200 Quickly

Process webhooks asynchronously. Return 200 immediately, then process in background.

Verify Signatures

Always verify webhook signatures to prevent spoofing

Handle Duplicates

Webhooks may be delivered more than once. Use idempotency keys.

Log Everything

Log all webhook events for debugging and auditing