> ## Documentation Index
> Fetch the complete documentation index at: https://docs.autosend.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Event Types

> Complete list of supported webhook event types and their payloads.

export const APP_PATHS = {
  home: '/',
  quickstart: '/quickstart',
  domainConfiguration: '/domain',
  apiReference: '/api-reference',
  sendEmail: '/api-reference/mails/send',
  bulkSendEmail: '/api-reference/mails/bulk',
  upsertContactApiRef: '/api-reference/contacts/upsert-contact',
  transactional: '/transactional-emails',
  emailActivity: '/transactional-emails/email-activity',
  emailTemplates: '/transactional-emails/email-templates',
  sendingEmail: '/quickstart/email-using-api',
  transactionalTroubleshooting: '/transactional-emails/troubleshooting',
  marketing: '/marketing-emails',
  campaigns: '/marketing-emails/campaigns',
  contacts: '/marketing-emails/contacts',
  contactsIntroduction: '/marketing-emails/contacts/introduction',
  contactsImportCsv: '/marketing-emails/contacts/import-csv',
  contactsLists: '/marketing-emails/contacts/lists',
  contactsSegments: '/marketing-emails/contacts/segments',
  contactsCustomFields: '/marketing-emails/contacts/custom-fields',
  sender: '/marketing-emails/sender',
  unsubscribeGroups: '/others/unsubscribe-groups',
  webhookIntroduction: '/others/webhooks/introduction',
  webhookEventType: '/others/webhooks/event-type',
  webhookRetries: '/others/webhooks/retries',
  webhookVerifyRequests: '/others/webhooks/verify-requests',
  dynamicTemplates: '/dynamic-templates',
  guides: '/guides',
  sitemap: '/sitemap.xml',
  team: '/others/team',
  automations: '/automations',
  smtpIntroduction: '/quickstart/smtp',
  betterAuth: '/guides/better-auth',
  templateVariables: '/transactional-emails/variables',
  suppressions: '/others/suppressions',
  rateLimit: '/api-reference/rate-limit',
  nodejsSdk: '/sdk/nodejs',
  smtpIntegrationGuides: '/guides/smtp',
  apiKeys: '/api-keys',
  apiReferenceIntroduction: '/api-reference/introduction',
  lovableGuide: '/ai/integrations/lovable',
  aiIntroduction: '/ai/introduction',
  aiSkills: '/ai/skills',
  aiMcpServer: '/ai/mcp-server',
  aiLovable: '/ai/integrations/lovable',
  aiBolt: '/ai/integrations/bolt',
  aiV0: '/ai/integrations/v0',
  aiReplit: '/ai/integrations/replit',
  mcpClaude: '/ai/mcp-clients/claude',
  mcpCursor: '/ai/mcp-clients/cursor',
  mcpCopilot: '/ai/mcp-clients/copilot',
  mcpWindsurf: '/ai/mcp-clients/windsurf',
  mcpCodex: '/ai/mcp-clients/codex',
  mcpAntigravity: '/ai/mcp-clients/antigravity',
  mcpChatgpt: '/ai/mcp-clients/chatgpt',
  mcpRaycast: '/ai/mcp-clients/raycast',
  domainWarmup: '/marketing-emails/domain-warmup',
  projects: '/projects',
  createAutomationApi: '/api-reference/automations/create-automation'
};

export const AUTOSEND_PATHS = {
  dashboard: 'https://autosend.com/dashboard',
  apiKey: 'https://autosend.com/account/api-key',
  faqs: 'https://autosend.com/faq',
  marketingEmails: 'https://autosend.com/marketing-emails',
  webhooks: 'https://autosend.com/webhooks',
  composeByAutoSend: 'https://autosend.com/compose',
  emailActivity: 'https://autosend.com/email-activities',
  team: 'https://autosend.com/settings/team',
  pricing: 'https://autosend.com/pricing',
  verifyEmail: 'https://autosend.com/compose/email-builder?template=verify-email',
  welcomeEmail: 'https://autosend.com/compose/email-builder?template=welcome-email',
  productUpdate: 'https://autosend.com/compose/email-builder?template=product-update',
  newsletter: 'https://autosend.com/compose/email-builder?template=newsletter',
  automations: 'https://autosend.com/automations',
  globalSuppressions: 'https://autosend.com/suppressions/global',
  signup: 'https://autosend.com/signup',
  domains: 'https://autosend.com/settings/domains',
  logoKit: 'https://asend.email/logo',
  contactsPage: 'https://autosend.com/contacts/list-and-segments'
};

## Overview

AutoSend webhooks support three categories of events:

1. **Email Lifecycle Events** - Track email sending and delivery
2. **Email Engagement Events** - Track how recipients interact with your emails
3. **Email Subscription Events** - Track unsubscribe and resubscribe actions
4. **Contact Events** - Track changes to your contact database

All webhook payloads follow this structure:

```json theme={null}
{
  "type": "event.type",
  "createdAt": "2025-11-12T10:30:00.000Z",
  "data": {
    "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
    "from": "sender@yourdomain.com",
    "to": {
      "email": "user@example.com",
      "name": "John Doe"
    },
    "subject": "Email Subject",
    "test": false,
    "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
    "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
    "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
    "batchId": "64f1a2b3c4d5e6f7g8h9i0j6"
    // Additional event-specific fields
  }
}
```

**Common Fields (for most email events):**

* `emailId` - Unique identifier for the email activity
* `from` - Sender email address
* `to` - Recipient object containing email and name
* `subject` - Email subject line
* `test` - Boolean indicating if this is a test email (true) or production (false)
* `campaignId` - Campaign identifier (optional)
* `templateId` - Template identifier (optional)
* `workflowAutomationId` - Workflow automation identifier (optional)
* `batchId` - Batch identifier (optional)

**Note:** Subscription events (`email.unsubscribed`, `email.group_unsubscribed`, `email.group_resubscribed`) and contact events have different structures for privacy reasons. See individual event details below.

## Supported Event Types

**Email Lifecycle:**

* `email.sent` - Email successfully sent to the recipient's mail server
* `email.delivered` - Email successfully delivered
* `email.deferred` - Email delivery temporarily delayed
* `email.bounced` - Email failed to deliver

**Email Engagement:**

* `email.opened` - Recipient opened the email
* `email.clicked` - Recipient clicked a link in the email
* `email.spam_reported` - Recipient marked email as spam

**Email Subscription:**

* `email.unsubscribed` - Recipient unsubscribed globally from all emails
* `email.group_unsubscribed` - Recipient unsubscribed from a specific email group
* `email.group_resubscribed` - Recipient resubscribed to a specific email group

**Contact Management:**

* `contact.created` - New contact created
* `contact.updated` - Contact information updated
* `contact.deleted` - Contact deleted

***

## Email Lifecycle Events

### `email.sent`

Triggered when an email is successfully sent to the recipient's mail server.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.sent",
    "createdAt": "2025-11-12T10:00:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "from": "sender@yourdomain.com",
      "to": {
        "email": "user@example.com",
        "name": "John Doe"
      },
      "subject": "Welcome to AutoSend",
      "test": false,
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
      "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
      "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
      "batchId": "64f1a2b3c4d5e6f7g8h9i0j6"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity
  * `from` - Sender email address
  * `to` - Recipient object with email and name
  * `subject` - Email subject line
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `campaignId` - Campaign ID (optional, if sent as part of a campaign)
  * `templateId` - Template ID used for the email (optional)
  * `workflowAutomationId` - Workflow automation ID (optional, if sent from automation)
  * `batchId` - Batch ID (optional, if sent as part of a batch)

  **Use Cases:**

  * Track when emails are successfully accepted by recipient server
  * Monitor email sending activity
  * Trigger follow-up workflows after email dispatch
</Accordion>

***

### `email.delivered`

Triggered when AutoSend successfully delivers an email to the recipient's mail server.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.delivered",
    "createdAt": "2025-11-12T10:15:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "from": "sender@yourdomain.com",
      "to": {
        "email": "user@example.com",
        "name": "John Doe"
      },
      "subject": "Welcome to AutoSend",
      "test": false,
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
      "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
      "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
      "batchId": "64f1a2b3c4d5e6f7g8h9i0j6"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity
  * `from` - Sender email address
  * `to` - Recipient object with email and name
  * `subject` - Email subject line
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `campaignId` - Campaign ID (optional, if applicable)
  * `templateId` - Template ID used (optional)
  * `workflowAutomationId` - Workflow automation ID (optional, if sent from automation)
  * `batchId` - Batch ID (optional, if sent as part of a batch)

  **Use Cases:**

  * Confirm successful email delivery
  * Update delivery status in your database
  * Track delivery times and patterns
</Accordion>

***

### `email.deferred`

Triggered when email delivery is temporarily delayed by the recipient's mail server.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.deferred",
    "createdAt": "2025-11-12T10:10:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "from": "sender@yourdomain.com",
      "to": {
        "email": "user@example.com",
        "name": "John Doe"
      },
      "subject": "Welcome to AutoSend",
      "test": false,
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
      "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
      "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
      "batchId": "64f1a2b3c4d5e6f7g8h9i0j6",
      "delayType": "InternalFailure",
      "delayReason": "Temporary connection failure",
      "expirationTime": "2025-11-12T14:10:00.000Z"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity
  * `from` - Sender email address
  * `to` - Recipient object with email and name
  * `subject` - Email subject line
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `campaignId` - Campaign ID (optional, if applicable)
  * `templateId` - Template ID used (optional)
  * `workflowAutomationId` - Workflow automation ID (optional, if sent from automation)
  * `batchId` - Batch ID (optional, if sent as part of a batch)
  * `delayType` - Type of delay, e.g., "InternalFailure", "MailboxFull" (optional)
  * `delayReason` - Human-readable explanation of the delay (optional)
  * `expirationTime` - ISO 8601 timestamp when delivery attempts will stop (optional)

  **Use Cases:**

  * Monitor temporary delivery issues
  * Track mail server responsiveness
  * Alert on persistent deferral patterns
</Accordion>

***

### `email.bounced`

Triggered when an email bounces (fails to deliver).

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.bounced",
    "createdAt": "2025-11-12T10:20:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "from": "sender@yourdomain.com",
      "to": {
        "email": "invalid@example.com",
        "name": "Invalid User"
      },
      "subject": "Welcome to AutoSend",
      "test": false,
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
      "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
      "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
      "batchId": "64f1a2b3c4d5e6f7g8h9i0j6",
      "bounceType": "Permanent",
      "bounceSubType": "General",
      "reason": "550 5.1.1 The email account that you tried to reach does not exist"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity
  * `from` - Sender email address
  * `to` - Recipient object with email and name
  * `subject` - Email subject line
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `campaignId` - Campaign ID (optional, if applicable)
  * `templateId` - Template ID used (optional)
  * `workflowAutomationId` - Workflow automation ID (optional, if sent from automation)
  * `batchId` - Batch ID (optional, if sent as part of a batch)
  * `bounceType` - Bounce classification: "Permanent" or "Transient" (optional)
  * `bounceSubType` - Detailed bounce category, e.g., "General", "NoEmail", "Suppressed" (optional)
  * `reason` - Human-readable bounce reason from the mail server (optional)

  **Bounce Types:**

  * `Permanent`: Hard bounce - invalid email address, domain doesn't exist
  * `Transient`: Soft bounce - mailbox full, server temporarily unavailable

  **Use Cases:**

  * Remove hard bounced emails from your list
  * Retry soft bounces later
  * Monitor bounce rates for sender reputation
</Accordion>

***

## Email Engagement Events

### `email.opened`

Triggered when a recipient opens an email.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.opened",
    "createdAt": "2025-11-12T10:30:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "from": "sender@yourdomain.com",
      "to": {
        "email": "user@example.com",
        "name": "John Doe"
      },
      "subject": "Welcome to AutoSend",
      "test": false,
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
      "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
      "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
      "batchId": "64f1a2b3c4d5e6f7g8h9i0j6"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity
  * `from` - Sender email address
  * `to` - Recipient object with email and name
  * `subject` - Email subject line
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `campaignId` - Campaign ID (optional, if applicable)
  * `templateId` - Template ID used (optional)
  * `workflowAutomationId` - Workflow automation ID (optional, if sent from automation)
  * `batchId` - Batch ID (optional, if sent as part of a batch)

  **Privacy Note:** This event does NOT include `ipAddress`, `userAgent`, `device`, or `location` information for privacy protection.

  **Use Cases:**

  * Track email engagement rates
  * Identify best send times
  * Segment engaged vs unengaged contacts
</Accordion>

***

### `email.clicked`

Triggered when a recipient clicks a link in an email.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.clicked",
    "createdAt": "2025-11-12T10:35:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "from": "sender@yourdomain.com",
      "to": {
        "email": "user@example.com",
        "name": "John Doe"
      },
      "subject": "Welcome to AutoSend",
      "test": false,
      "clickedUrl": "https://example.com/product",
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
      "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
      "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
      "batchId": "64f1a2b3c4d5e6f7g8h9i0j6"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity
  * `from` - Sender email address
  * `to` - Recipient object with email and name
  * `subject` - Email subject line
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `clickedUrl` - The URL that was clicked (optional)
  * `campaignId` - Campaign ID (optional, if applicable)
  * `templateId` - Template ID used (optional)
  * `workflowAutomationId` - Workflow automation ID (optional, if sent from automation)
  * `batchId` - Batch ID (optional, if sent as part of a batch)

  **Privacy Note:** This event does NOT include `ipAddress`, `userAgent`, or `device` information for privacy protection.

  **Use Cases:**

  * Track which links are most popular
  * Identify highly engaged contacts
  * Trigger follow-up campaigns based on clicked links
</Accordion>

***

### `email.spam_reported`

Triggered when a recipient marks an email as spam or files a complaint.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.spam_reported",
    "createdAt": "2025-11-12T10:45:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "from": "sender@yourdomain.com",
      "to": {
        "email": "user@example.com",
        "name": "John Doe"
      },
      "subject": "Welcome to AutoSend",
      "test": false,
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
      "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
      "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
      "batchId": "64f1a2b3c4d5e6f7g8h9i0j6",
      "complaintType": "abuse"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity
  * `from` - Sender email address
  * `to` - Recipient object with email and name
  * `subject` - Email subject line
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `campaignId` - Campaign ID (optional, if applicable)
  * `templateId` - Template ID used (optional)
  * `workflowAutomationId` - Workflow automation ID (optional, if sent from automation)
  * `batchId` - Batch ID (optional, if sent as part of a batch)
  * `complaintType` - Type of complaint: "abuse", "fraud", "virus", "other" (optional)

  **Use Cases:**

  * Automatically suppress emails that file complaints
  * Monitor spam complaint rates
  * Improve email content and targeting to reduce complaints
  * Protect sender reputation
</Accordion>

***

## Email Subscription Events

### `email.unsubscribed`

Triggered when a recipient globally unsubscribes from **all** emails.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.unsubscribed",
    "createdAt": "2025-11-12T10:40:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "test": false,
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
      "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
      "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
      "batchId": "64f1a2b3c4d5e6f7g8h9i0j6"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity (optional - only present if triggered from an email)
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `campaignId` - Campaign ID (optional - only present if triggered from a campaign email)
  * `templateId` - Template ID (optional - only present if triggered from an email)
  * `workflowAutomationId` - Workflow automation ID (optional - only present if triggered from automation email)
  * `batchId` - Batch ID (optional - only present if triggered from batch email)

  **Important Notes:**

  * This event does **NOT** include `from`, `to`, or `subject` fields for privacy protection
  * Fields like `emailId`, `campaignId`, `templateId`, `workflowAutomationId`, and `batchId` are **optional** and only present when the unsubscribe is triggered from an email context

  **Use Cases:**

  * Automatically remove contacts from all mailing lists
  * Update contact preferences in your CRM
  * Track global unsubscribe reasons for analytics
  * Ensure compliance with email regulations
</Accordion>

***

### `email.group_unsubscribed`

Triggered when a recipient unsubscribes from a specific email group or suppression group (but not all emails).

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.group_unsubscribed",
    "createdAt": "2025-11-12T10:42:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "test": false,
      "unsubscribeGroupId": "newsletter-marketing",
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2",
      "templateId": "64f1a2b3c4d5e6f7g8h9i0j4",
      "workflowAutomationId": "64f1a2b3c4d5e6f7g8h9i0j5",
      "batchId": "64f1a2b3c4d5e6f7g8h9i0j6"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity (optional - only present if triggered from an email)
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `unsubscribeGroupId` - The specific group ID they unsubscribed from (optional)
  * `campaignId` - Campaign ID (optional - only present if triggered from a campaign email)
  * `templateId` - Template ID (optional - only present if triggered from an email)
  * `workflowAutomationId` - Workflow automation ID (optional - only present if triggered from automation email)
  * `batchId` - Batch ID (optional - only present if triggered from batch email)

  **Important Notes:**

  * This event does **NOT** include `from`, `to`, or `subject` fields for privacy protection
  * Fields like `emailId`, `campaignId`, `templateId`, `workflowAutomationId`, and `batchId` are **optional** and only present when the unsubscribe is triggered from an email context

  **Use Cases:**

  * Remove contacts from specific mailing lists or segments
  * Allow granular subscription management
  * Track which email categories users opt out of
  * Maintain subscriber preferences across different email types
</Accordion>

***

### `email.group_resubscribed`

Triggered when a recipient resubscribes to a specific email group they previously unsubscribed from.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "email.group_resubscribed",
    "createdAt": "2025-11-12T11:00:00.000Z",
    "data": {
      "emailId": "64f1a2b3c4d5e6f7g8h9i0j1",
      "test": false,
      "unsubscribeGroupId": "newsletter-marketing",
      "campaignId": "64f1a2b3c4d5e6f7g8h9i0j2"
    }
  }
  ```

  **Data Fields:**

  * `emailId` - Unique identifier for the email activity (optional)
  * `test` - Boolean indicating whether this is a test email (true) or production (false)
  * `unsubscribeGroupId` - The specific group ID they resubscribed to (optional)
  * `campaignId` - Campaign ID (optional)

  **Important Notes:**

  * This event does **NOT** include `from`, `to`, or `subject` fields for privacy protection

  **Use Cases:**

  * Re-add contacts to specific mailing lists
  * Track re-engagement patterns
  * Update subscription preferences in your CRM
  * Resume sending specific types of emails to the contact
</Accordion>

***

## Contact Events

### `contact.created`

Triggered when a new contact is created in your AutoSend project.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "contact.created",
    "createdAt": "2025-11-12T09:00:00.000Z",
    "data": {
      "contactId": "64f1a2b3c4d5e6f7g8h9i0j3",
      "email": "newuser@example.com",
      "name": "John Doe"
    }
  }
  ```

  **Data Fields:**

  * `contactId` - Unique identifier for the contact (optional)
  * `email` - Contact's email address (optional)
  * `name` - Contact's name (optional)

  **Note:** Additional custom fields may be included based on your contact schema.

  **Use Cases:**

  * Sync new contacts to your CRM
  * Trigger welcome email sequences
  * Update analytics dashboards
  * Initialize contact tracking in external systems
</Accordion>

***

### `contact.updated`

Triggered when an existing contact's information is updated.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "contact.updated",
    "createdAt": "2025-11-12T09:30:00.000Z",
    "data": {
      "contactId": "64f1a2b3c4d5e6f7g8h9i0j3",
      "email": "user@example.com",
      "name": "Jonathan Doe",
      "changedFields": ["name"]
    }
  }
  ```

  **Data Fields:**

  * `contactId` - Unique identifier for the contact (optional)
  * `email` - Contact's email address (optional)
  * `name` - Contact's name (optional)
  * `changedFields` - List of field names that were changed (optional)

  **Note:** Additional custom fields may be included based on your contact schema.

  **Use Cases:**

  * Keep contact data synchronized across systems
  * Track contact lifecycle changes
  * Trigger workflows based on specific field changes
  * Update contact profiles in external databases
</Accordion>

***

### `contact.deleted`

Triggered when a contact is deleted from your AutoSend project.

<Accordion title="Payload and use case">
  **Sample Payload:**

  ```json theme={null}
  {
    "type": "contact.deleted",
    "createdAt": "2025-11-12T09:45:00.000Z",
    "data": {
      "contactId": "64f1a2b3c4d5e6f7g8h9i0j3",
      "email": "deleteduser@example.com"
    }
  }
  ```

  **Data Fields:**

  * `contactId` - Unique identifier for the deleted contact (optional)
  * `email` - Contact's email address for reference (optional)

  **Use Cases:**

  * Remove contacts from external systems
  * Update contact counts and analytics
  * Maintain data consistency across platforms
  * Ensure GDPR/privacy compliance in external systems
</Accordion>

***

## Event Handling Examples

<CodeGroup>
  ```javascript Handle Multiple Events expandable theme={null}
  app.post("/webhooks/autosend", async (req, res) => {
    const { type, data } = req.body;

    switch (type) {
      case "email.sent":
        await handleEmailSent(data);
        break;

      case "email.delivered":
        await handleEmailDelivered(data);
        break;

      case "email.deferred":
        await handleEmailDeferred(data);
        break;

      case "email.opened":
        await handleEmailOpened(data);
        break;

      case "email.clicked":
        await handleEmailClicked(data);
        break;

      case "email.bounced":
        await handleEmailBounced(data);
        break;

      case "email.spam_reported":
        await handleSpamReport(data);
        break;

      case "email.unsubscribed":
        await handleGlobalUnsubscribe(data);
        break;

      case "email.group_unsubscribed":
        await handleGroupUnsubscribe(data);
        break;

      case "email.group_resubscribed":
        await handleGroupResubscribe(data);
        break;

      case "contact.created":
        await handleContactCreated(data);
        break;

      case "contact.updated":
        await handleContactUpdated(data);
        break;

      case "contact.deleted":
        await handleContactDeleted(data);
        break;

      default:
        console.log(`Unhandled event: ${type}`);
    }

    res.status(200).json({ received: true });

  });

  ```

  ```javascript Track Email Engagement expandable theme={null}
  async function handleEmailOpened(data) {
    const { emailId, to } = data;

    await db.emails.update({
      where: { id: emailId },
      data: {
        opened: true,
        openedAt: new Date(),
        opens: { increment: 1 },
      },
    });

    await db.contacts.update({
      where: { email: to.email },
      data: {
        lastEngagement: new Date(),
        engagementScore: { increment: 1 },
      },
    });
  }

  async function handleEmailClicked(data) {
    const { emailId, to, clickedUrl } = data;

    await db.clicks.create({
      data: {
        emailId,
        recipientEmail: to.email,
        url: clickedUrl,
        clickedAt: new Date(),
      },
    });

    await db.contacts.update({
      where: { email: to.email },
      data: {
        lastEngagement: new Date(),
        engagementScore: { increment: 5 },
      },
    });
  }
  ```

  ```javascript Handle Bounces and Complaints expandable theme={null}
  async function handleEmailBounced(data) {
    const { to, bounceType, reason } = data;

    if (bounceType === 'Permanent') {
      // Remove from active mailing lists
      await db.contacts.update({
        where: { email: to.email },
        data: {
          status: 'bounced',
          bouncedAt: new Date(),
          bounceReason: reason,
        },
      });

      // Suppress future emails
      await db.suppressions.create({
        data: {
          email: to.email,
          type: 'bounce',
          reason: reason,
        },
      });

      // Alert team
      await sendAlert(`Hard bounce for ${to.email}: ${reason}`);
    }
  }

  async function handleSpamReport(data) {
    const { to } = data;
    const email = to.email;

    // Immediately suppress the email
    await db.suppressions.create({
      data: {
        email,
        type: 'complaint',
        reportedAt: new Date(),
      },
    });

    // Update contact status
    await db.contacts.update({
      where: { email },
      data: {
        status: 'complained',
        complainedAt: new Date(),
      },
    });

    // Alert team for reputation monitoring
    await sendAlert(`Spam complaint from ${email}`);
  }
  ```

  ```javascript Handle Subscription Events expandable theme={null}
  async function handleGlobalUnsubscribe(data) {
    const { emailId, campaignId } = data;

    // Update email activity record
    await db.emails.update({
      where: { id: emailId },
      data: {
        unsubscribed: true,
        unsubscribedAt: new Date(),
      },
    });

    console.log(
      `Global unsubscribe from email ${emailId}, campaign ${campaignId}`
    );
  }

  async function handleGroupUnsubscribe(data) {
    const { emailId, unsubscribeGroupId, campaignId } = data;

    // Update email activity record
    await db.emails.update({
      where: { id: emailId },
      data: {
        groupUnsubscribed: true,
        unsubscribeGroupId,
        unsubscribedAt: new Date(),
      },
    });

    console.log(
      `Group unsubscribe from email ${emailId}, group ${unsubscribeGroupId}`
    );
  }

  async function handleGroupResubscribe(data) {
    const { emailId, unsubscribeGroupId } = data;

    // Update subscription record
    await db.emails.update({
      where: { id: emailId },
      data: {
        resubscribed: true,
        resubscribeGroupId: unsubscribeGroupId,
        resubscribedAt: new Date(),
      },
    });

    console.log(
      `Group resubscribe for email ${emailId}, group ${unsubscribeGroupId}`
    );
  }
  ```

  ```javascript Sync Contacts expandable theme={null}
  async function handleContactCreated(data) {
    const { contactId, email, name } = data;

    // Sync to CRM
    await crm.contacts.create({
      externalId: contactId,
      email,
      name,
      createdAt: new Date(),
    });
  }

  async function handleContactUpdated(data) {
    const { contactId, email, name, changedFields } = data;

    // Sync to CRM
    await crm.contacts.update({
      externalId: contactId,
      email,
      name,
      changedFields,
      updatedAt: new Date(),
    });
  }

  async function handleContactDeleted(data) {
    const { contactId, email } = data;

    // Remove from CRM
    await crm.contacts.delete({
      externalId: contactId,
    });

    console.log(`Contact ${email} removed from CRM`);
  }
  ```
</CodeGroup>

***

## Get Available Events via API

You can programmatically fetch the list of available events:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.autosend.com/v1/webhooks/events/available \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "x-project-id: YOUR_PROJECT_ID"
  ```

  ```javascript Node.js expandable theme={null}
  const fetch = require('node-fetch');

  const API_KEY = process.env.AUTOSEND_API_KEY;
  const PROJECT_ID = process.env.AUTOSEND_PROJECT_ID;

  async function getAvailableEvents() {
    const response = await fetch(
      'https://api.autosend.com/v1/webhooks/events/available',
      {
        method: 'GET',
        headers: {
          Authorization: `Bearer ${API_KEY}`,
          'x-project-id': PROJECT_ID,
        },
      }
    );

    const data = await response.json();
    console.log(data);
    return data;
  }

  getAvailableEvents();
  ```

  ```python Python expandable theme={null}
  import requests
  import os

  API_KEY = os.environ.get('AUTOSEND_API_KEY')
  PROJECT_ID = os.environ.get('AUTOSEND_PROJECT_ID')

  def get_available_events():
      url = 'https://api.autosend.com/v1/webhooks/events/available'
      headers = {
          'Authorization': f'Bearer {API_KEY}',
          'x-project-id': PROJECT_ID
      }

      response = requests.get(url, headers=headers)
      data = response.json()
      print(data)
      return data

  get_available_events()
  ```

  ```php PHP expandable theme={null}
  <?php

  $apiKey = getenv('AUTOSEND_API_KEY');
  $projectId = getenv('AUTOSEND_PROJECT_ID');

  $ch = curl_init('https://api.autosend.com/v1/webhooks/events/available');

  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer ' . $apiKey,
      'x-project-id: ' . $projectId
  ]);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  $data = json_decode($response, true);
  curl_close($ch);

  print_r($data);
  ?>
  ```

  ```go Go expandable theme={null}
  package main

  import (
      "fmt"
      "io"
      "net/http"
      "os"
  )

  func main() {
      apiKey := os.Getenv("AUTOSEND_API_KEY")
      projectId := os.Getenv("AUTOSEND_PROJECT_ID")

      req, _ := http.NewRequest("GET", "https://api.autosend.com/v1/webhooks/events/available", nil)
      req.Header.Set("Authorization", "Bearer "+apiKey)
      req.Header.Set("x-project-id", projectId)

      client := &http.Client{}
      resp, _ := client.Do(req)
      defer resp.Body.Close()

      body, _ := io.ReadAll(resp.Body)
      fmt.Println(string(body))
  }
  ```

  ```ruby Ruby expandable theme={null}
  require 'net/http'
  require 'json'
  require 'uri'

  api_key = ENV['AUTOSEND_API_KEY']
  project_id = ENV['AUTOSEND_PROJECT_ID']

  uri = URI('https://api.autosend.com/v1/webhooks/events/available')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Get.new(uri)
  request['Authorization'] = "Bearer #{api_key}"
  request['x-project-id'] = project_id

  response = http.request(request)
  data = JSON.parse(response.body)
  puts data
  ```
</CodeGroup>

**Response:**

```json expandable theme={null}
{
  "success": true,
  "data": {
    "events": [
      "email.sent",
      "email.delivered",
      "email.deferred",
      "email.opened",
      "email.clicked",
      "email.bounced",
      "email.spam_reported",
      "email.unsubscribed",
      "email.group_unsubscribed",
      "email.group_resubscribed",
      "contact.created",
      "contact.updated",
      "contact.deleted"
    ]
  }
}
```

***

## Related Resources

<Columns cols={2}>
  <Card title="Introduction" icon="https://mintcdn.com/autosend-13920f5c/nx_wYfWx3qeZwg1C/icons/introduction.svg?fit=max&auto=format&n=nx_wYfWx3qeZwg1C&q=85&s=9b4ef691e39d4517b800d381b32a89db" href={APP_PATHS.webhookIntroduction} width="24" height="24" data-path="icons/introduction.svg">
    Getting started with webhooks
  </Card>

  {' '}

  <Card title="Retries and Replays" icon="https://mintcdn.com/autosend-13920f5c/nx_wYfWx3qeZwg1C/icons/retries-refresh.svg?fit=max&auto=format&n=nx_wYfWx3qeZwg1C&q=85&s=6c8bfc5edaa01d3624986eebbb4cbb09" href={APP_PATHS.webhookRetries} width="24" height="24" data-path="icons/retries-refresh.svg">
    Automatic retry logic and best practices
  </Card>

  {' '}

  <Card title="Verify Webhook Requests" icon="https://mintcdn.com/autosend-13920f5c/nx_wYfWx3qeZwg1C/icons/verify-requests.svg?fit=max&auto=format&n=nx_wYfWx3qeZwg1C&q=85&s=dec233ef8a7a82b41b8ab4d6540904ec" href={APP_PATHS.webhookVerifyRequests} width="24" height="24" data-path="icons/verify-requests.svg">
    Security and signature verification
  </Card>

  <Card title="Webhooks" icon="https://mintcdn.com/autosend-13920f5c/nx_wYfWx3qeZwg1C/icons/webhook.svg?fit=max&auto=format&n=nx_wYfWx3qeZwg1C&q=85&s=14ad6675c71731ac04f786559a813ee1" href={AUTOSEND_PATHS.webhooks} width="24" height="24" data-path="icons/webhook.svg">
    Manage your webhooks from the AutoSend sidebar
  </Card>
</Columns>
