# Webhooks

Configure and manage webhooks to receive email events in your application.

Use webhooks to push real-time email notifications to your application. All webhooks use HTTPS and deliver a JSON payload that can be used by your application.

# **Add/Update Webhook**

Register new or update existing webhooks to receive email event notifications.

## Request Header

```http
POST https://api.cm.com/email/webhook/v1/accounts/{logicalAccountId}/create
Content-Type: application/json
```

| **Parameter**    | **Type** | **Required** | **Description**                |
| ---------------- | -------- | ------------ | ------------------------------ |
| logicalAccountId | UUID     | Yes          | The logical account identifier |

| **Header Name** | **Type** | **Required** | **Description**            |
| --------------- | -------- | ------------ | -------------------------- |
| Content-Type    | string   | Yes          | Must be "application/json" |
| Authorization   | string   | Yes          | Valid authorization token  |

## Request Body

```json
{
  "webhookType": "delivered",
  "webhookUrl": "https://your-domain.com/webhook/email-events"
}
```
```yaml
webhookType: "delivered"
webhookUrl: "https://your-domain.com/webhook/email-events"
```

Use one of the following supported webhook types:

| **Webhook Type** | **Enum Value** | **Description**               | **Events Included**                  |
| ---------------- | -------------- | ----------------------------- | ------------------------------------ |
| global           | 0              | All email events              | All email events in single webhook   |
| delivered        | 1              | Successful email deliveries   | Email delivered to recipient's inbox |
| opened           | 2              | Email opens                   | Recipient opened the email           |
| clicked          | 3              | Email link clicks             | Recipient clicked on email links     |
| bounced          | 4              | Email bounces (hard and soft) | Failed delivery attempts             |
| unsubscribed     | 5              | Unsubscribe events            | Recipient unsubscribed               |
| complained       | 6              | Spam complaints               | Email marked as spam                 |
| failed           | 7              | Email send failures           | Email failed to send                 |
| sent             | 8              | Email sent successfully       | Email accepted and sent from server  |
| suppressed       | 9              | Suppressed emails             | Email suppressed from sending        |

## Response Body

```json
{
    "success": true,
    "status": 200,
    "message": "Successfully created/updated webhook with id 148",
    "data": 148
}
```
```yaml
success: true
status: 200
message: "Successfully created/updated webhook with id 148"
data: 148
```

## Errors Responses

**Invalid Request Body (400)**

```json
{
  "success": false,
  "status": 400,
  "message": "Provide a valid url for webhook.",
  "data": 0
}
```
```yaml
success: false
status: 400
message: "Provide a valid url for webhook."
data: 0
```

**Invalid Account ID (400)**

```json
{
  "success": false,
  "status": 400,
  "message": "Logical account id is not valid.",
  "data": 0
}
```
```yaml
success: false
status: 400
message: "Logical account id is not valid."
data: 0
```

**Invalid Webhook Type (400)**

```json
{
  "success": false,
  "status": 400,
  "message": "Invalid webhook type: opened1",
  "data": 0
}
```
```yaml
success: false
status: 400
message: "Invalid webhook type: opened1"
data: 0
```

**Invalid Webhook URL (400)**

```json
{
  "success": false,
  "status": 400,
  "message": "Provide a valid url for webhook.",
  "data": 0
}
```
```yaml
success: false
status: 400
message: "Provide a valid url for webhook."
data: 0
```

***

# **Get Webhook**

Retrieve webhook configuration for a specific account and webhook type.

## Request Header

```http
GET https://api.cm.com/email/webhook/v1/accounts/{logicalAccountId}/list?webhookType={webhookType}
```

| **Parameter**    | **Type** | **Required** | **Description**                |
| ---------------- | -------- | ------------ | ------------------------------ |
| logicalAccountId | UUID     | Yes          | The logical account identifier |

| **Parameter** | **Type** | **Required** | **Description**                                                  |
| ------------- | -------- | ------------ | ---------------------------------------------------------------- |
| webhookType   | string   | No           | Specific webhook type to retrieve (e.g., "delivered", "bounced") |

## Response Body

**Successful Response - Specific Webhook (200)**

```json
{
    "success": true,
    "status": 200,
    "message": "Successfully retrieved webhook for account 903e1cef-84b3-4500-a9a5-b2ca219f76f5 and type 1",
    "data": {
        "webhookType": 1,
        "url": "https://webhook.site/547a4f29-49a2-4d06-98db-2a721b563f01"
    }
}
```
```yaml
success: true
status: 200
message: "Successfully retrieved webhook for account 903e1cef-84b3-4500-a9a5-b2ca219f76f5 and type 1"
data:
  webhookType: 1
  url: "https://webhook.site/547a4f29-49a2-4d06-98db-2a721b563f01"
```

**Successful Response - No Webhook Found (200)**

```json
{
    "success": true,
    "status": 200,
    "message": "Webhook type not found.",
    "data": null
}
```
```yaml
success: true
status: 200
message: "Webhook type not found."
data: null
```

**Successful Response - Webhook Types (200)**

When `webhookType` is empty or "-1", returns available webhook types:

```json
{
  "success": true,
  "status": 200,
  "message": "Successfully retrieved webhook type for account 903e1cef-84b3-4500-a9a5-b2ca219f76f5",
  "data": "global"
}
```
```yaml
success: true
status: 200
message: "Successfully retrieved webhook type for account 903e1cef-84b3-4500-a9a5-b2ca219f76f5"
data: "global"
```

## Error Responses

**Invalid Account ID (400)**

```json
{
  "success": false,
  "status": 400,
  "message": "Invalid account ID provided",
  "data": null
}
```
```yaml
success: false
status: 400
message: "Invalid account ID provided"
data: null
```

**Webhook Not Found (404)**

```json
{
  "success": false,
  "status": 404,
  "message": "Webhook type not found",
  "data": null
}
```
```yaml
success: false
status: 404
message: "Webhook type not found"
data: null
```

***

# **Delete Webhook**

Remove a webhook configuration for a specific account and webhook type.

## Request Header

```http
DELETE https://api.cm.com/email/webhook/v1/accounts/{logicalAccountId}/delete?webhookType={webhookType}
```

| **Parameter**    | **Type** | **Required** | **Description**                |
| ---------------- | -------- | ------------ | ------------------------------ |
| logicalAccountId | UUID     | Yes          | The logical account identifier |

| **Parameter** | **Type** | **Required** | **Description**                                                  |
| ------------- | -------- | ------------ | ---------------------------------------------------------------- |
| webhookType   | string   | Yes          | Webhook type to delete (e.g., "delivered", "bounced", "clicked") |

## Response Body

**Successful Response (200)**

```json
{
    "status": 200,
    "message": "Successfully deleted 1 webhook(s)",
    "success": true
}
```
```yaml
status: 200
message: "Successfully deleted 1 webhook(s)"
success: true
```

**Successful Response - No Webhook Found (200)**

```json
{
  "status": 200,
  "message": "No webhook found to delete",
  "success": true
}
```
```yaml
status: 200
message: "No webhook found to delete"
success: true
```

## Error Responses

**Invalid Account ID (400)**

```json
{
  "status": 400,
  "message": "Invalid account Id provided",
  "success": false
}
```
```yaml
status: 400
message: "Invalid account Id provided"
success: false
```

**Invalid Webhook Type (400)**

```json
{
  "status": 400,
  "message": "Invalid webhook type: bounced1",
  "success": false
}
```
```yaml
status: 400
message: "Invalid webhook type: bounced1"
success: false
```

***

# **Request Parameters**

## Request Body Fields

| **Field**   | **Type** | **Required** | **Description**                                                                                                                     |
| ----------- | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| webhookType | string   | Yes          | Type of webhook: "global", "delivered", "opened", "clicked", "bounced", "unsubscribed", "complained", "failed", "sent", "suspended" |
| webhookUrl  | string   | Yes          | HTTPS URL endpoint to receive webhook notifications                                                                                 |

## Response Object

| **Field**   | **Type** | **Description**                 |
| ----------- | -------- | ------------------------------- |
| webhookType | string   | Type of webhook events          |
| url         | string   | Configured webhook endpoint URL |

## Webhook URL Requirements

| **Requirement** | **Description**                                       |
| --------------- | ----------------------------------------------------- |
| Protocol        | Must use HTTPS for security                           |
| Accessibility   | Must be publicly accessible from CM servers           |
| Response        | Should respond with 200 status for successful receipt |

## Status Codes

| **Status Code** | **Description**                                 |
| --------------- | ----------------------------------------------- |
| 200             | OK: Request processed successfully              |
| 400             | Bad Request: Invalid request data or parameters |
| 404             | Not Found: Requested webhook not found          |
| 500             | Internal Server Error: Server-side error        |

# **Event Payload Structure**

When events occur, webhooks will receive POST requests with payloads like:

```json
{
  "type": "string",
  "createdAt": "string",
  "messageId": "GUID string",
  "data": {
    "to": "string",
    "from": "string",
    "id": "GUID string",
    "customerReference": "string",
    "unsubscribe": {
      "type": "string",
      "message": "string"
    },
    "bounce": {
      "type": "string",
      "subType": "string",
      "message": "string"
    },
    "failed": {
      "messages": [
        "string 1", 
        "string 2"
      ]
    }
  }
}
```
```yaml
type: "string"
createdAt: "string"
messageId: "GUID string"
data:
  to: "string"
  from: "string"
  id: "GUID string"
  customerReference: "string"
  unsubscribe:
    type: "string"
    message: "string"
  bounce:
    type: "string"
    subType: "string"
    message: "string"
  failed:
    messages:
      - "string 1"
      - "string 2"
```

For all webhook events, see our [Event Types page](https://developers.cm.com/messaging/docs/webhook-event-types).

# **Multi-Webhook Setup Example**

Configure different webhooks for different event types:

```bash
# Delivery tracking
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "delivered",
  "webhookUrl": "https://your-app.com/webhooks/delivered"
}

# Sent tracking
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "sent",
  "webhookUrl": "https://your-app.com/webhooks/sent"
}

# Bounce management
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "bounced",
  "webhookUrl": "https://your-app.com/webhooks/bounces"
}

# Open tracking
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "opened",
  "webhookUrl": "https://analytics.your-app.com/email-opens"
}

# Click tracking
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "clicked",
  "webhookUrl": "https://analytics.your-app.com/email-clicks"
}

# Unsubscribe handling
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "unsubscribed",
  "webhookUrl": "https://your-app.com/webhooks/unsubscribes"
}

# Spam report monitoring
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "complained",
  "webhookUrl": "https://your-app.com/webhooks/spam-reports"
}
  
# Failed email tracking
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "failed",
  "webhookUrl": "https://your-app.com/webhooks/failed"
}

# Suppressed email tracking
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "suppressed",
  "webhookUrl": "https://your-app.com/webhooks/suppressed"
}
```