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

POST https://api.cm.com/email/webhook/v1/accounts/{logicalAccountId}/create
Content-Type: application/json
ParameterTypeRequiredDescription
logicalAccountIdUUIDYesThe logical account identifier
Header NameTypeRequiredDescription
Content-TypestringYesMust be "application/json"
AuthorizationstringYesValid authorization token

Request Body

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

Use one of the following supported webhook types:

Webhook TypeEnum ValueDescriptionEvents Included
global0All email eventsAll email events in single webhook
delivered1Successful email deliveriesEmail delivered to recipient's inbox
opened2Email opensRecipient opened the email
click3Email link clicksRecipient clicked on email links
bounces4Email bounces (hard and soft)Failed delivery attempts
unsubscribes5Unsubscribe eventsRecipient unsubscribed
spamreports6Spam complaintsEmail marked as spam

Response Body

{
  "isSuccess": true,
  "statusCode": "Ok",
  "message": "Successfully created/updated webhook with id 123",
  "data": 123
}

Errors Responses

Invalid Request Body (400)

{
  "isSuccess": false,
  "statusCode": "InvalidRequest",
  "message": "Request body is not valid",
  "data": 0
}

Invalid Account ID (400)

{
  "isSuccess": false,
  "statusCode": "InvalidRequest", 
  "message": "Logical account id is not valid",
  "data": 0
}

Invalid Webhook Type (400)

{
  "isSuccess": false,
  "statusCode": "InvalidRequest",
  "message": "Webhook type is not valid",
  "data": 0
}

Invalid Webhook URL (400)

{
  "isSuccess": false,
  "statusCode": "InvalidRequest",
  "message": "Provide a valid url for webhook",
  "data": 0
}

Get Webhook

Retrieve webhook configuration for a specific account and webhook type.

Request Header

GET https://api.cm.com/email/webhook/v1/accounts/{logicalAccountId}/list?webhookType={webhookType}
ParameterTypeRequiredDescription
logicalAccountIdUUIDYesThe logical account identifier
ParameterTypeRequiredDescription
webhookTypestringNoSpecific webhook type to retrieve (e.g., "delivered", "bounces")

Response Body

Successful Response - Specific Webhook (200)

{
  "isSuccess": true,
  "statusCode": "Ok", 
  "message": "Successfully retrieved webhook for account 903e1cef-84b3-4500-a9a5-b2ca219f76f5 and type delivered",
  "data": {
    "webhookType": "delivered",
    "url": "https://your-domain.com/webhook/email-events"
  }
}

Successful Response - No Webhook Found (200)

{
  "isSuccess": true,
  "statusCode": "Ok",
  "message": "No webhook found for account 903e1cef-84b3-4500-a9a5-b2ca219f76f5 and type delivered",
  "data": null
}

Successful Response - Webhook Types (200)

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

{
  "isSuccess": true,
  "statusCode": "Ok",
  "message": "Successfully retrieved webhook type for account 903e1cef-84b3-4500-a9a5-b2ca219f76f5",
  "data": "global"
}

Error Responses

Invalid Account ID (400)

{
  "isSuccess": false,
  "statusCode": "InvalidRequest",
  "message": "Invalid account ID provided",
  "data": null
}

Webhook Not Found (404)

{
  "isSuccess": false,
  "statusCode": "NotFound",
  "message": "Webhook type not found",
  "data": null
}

Delete Webhook

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

Request Header

DELETE https://api.cm.com/email/webhook/v1/accounts/{logicalAccountId}/delete?webhookType={webhookType}
ParameterTypeRequiredDescription
logicalAccountIdUUIDYesThe logical account identifier
ParameterTypeRequiredDescription
webhookTypestringYesWebhook type to delete (e.g., "delivered", "bounces", "click")

Response Body

Successful Response (200)

{
  "statusCode": "Ok",
  "statusMessage": "Successfully deleted 1 webhook(s)"
}

Successful Response - No Webhook Found (200)

{
  "statusCode": "Ok", 
  "statusMessage": "No webhook found to delete"
}

Error Responses

Invalid Account ID (400)

{
  "statusCode": "InvalidRequest",
  "statusMessage": "Invalid account ID provided"
}

Invalid Webhook Type (400)

{
  "statusCode": "InvalidRequest",
  "statusMessage": "Webhook type is not valid"
}

Request Parameters

Request Body Fields

FieldTypeRequiredDescription
webhookTypestringYesType of webhook: "global", "delivered", "opened", "click", "bounces", "unsubscribes", "spamreports"
webhookUrlstringYesHTTPS URL endpoint to receive webhook notifications

Response Object

FieldTypeDescription
webhookTypestringType of webhook events
urlstringConfigured webhook endpoint URL

Webhook URL Requirements

RequirementDescription
ProtocolMust use HTTPS for security
AccessibilityMust be publicly accessible from CM servers
ResponseShould respond with 200 status for successful receipt

Status Codes

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

Event Payload Structure

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

{
  "type": "Delivery",
  "id": "997c9d54954211f08d304e376c606893",
  "sender": "e60556f8-e5cd-4e5b-bf96-cbea917c2df5@cm903e1cef84b34500a9a5b2ca219f76f5.bondjorno.nl",
  "recipient": "[email protected]",
  "queue": "[email protected]",
  "site": "ip-1->smtp.cm.com@smtp_client",
  "size": 2901,
  "response": {
    "code": 250,
    "enhanced_code": null,
    "content": "mail saved",
    "command": ".\r\n"
  },
  "peer_address": {
    "name": "smtp.cm.com.",
    "addr": "87.98.164.155"
  },
  "timestamp": 1758277373,
  "created": 1758277372,
  "num_attempts": 0,
  "bounce_classification": "Uncategorized",
  "egress_pool": "pool-1",
  "egress_source": "ip-1",
  "source_address": {
    "address": "185.162.145.0:38349",
    "protocol": "socks5",
    "server": "10.0.65.203:5000"
  },
  "feedback_report": null,
  "meta": {},
  "headers": {
    "Message-ID": "<[email protected]>",
    "x-message-id": "e60556f8-e5cd-4e5b-bf96-cbea917c2df5",
    "x-logical-account-id": "903e1cef-84b3-4500-a9a5-b2ca219f76f5",
    "x-email-kind": "Market",
    "x-original-sender": "[email protected]"
  },
  "delivery_protocol": "ESMTP",
  "reception_protocol": "HTTP",
  "nodeid": "02573077-d52f-4ed3-9d8b-54253794935a",
  "tls_cipher": "TLS13_AES_256_GCM_SHA384",
  "tls_protocol_version": "TLSv1_3",
  "tls_peer_subject_name": [
    "CN=smtp.cm.com"
  ],
  "session_id": "b97c9756-fab5-4855-82ae-b05c84c07124",
  "unsubscribe_type": "",
  "email_type": "",
  "reason": ""
}

Please note that the availability of property data may vary depending on the type of webhook event. For instance, properties such as unsubscribeType and reason will not contain values for events of the "Delivery" type.

Multi-Webhook Setup Example

Configure different webhooks for different event types:

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

# Bounce management
POST /v1/accounts/903e1cef-84b3-4500-a9a5-b2ca219f76f5/create
{
  "webhookType": "bounces",
  "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": "click",
  "webhookUrl": "https://analytics.your-app.com/email-clicks"
}

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

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