Webhooks are user-defined HTTP callbacks which create notifications by Atlas events to destination systems.
Webhook Topics
Topic | Category | Description |
---|---|---|
account.customer.linked | ACCOUNT | Subscribe to customer linked to an account changes |
account.customer.unlinked | ACCOUNT | Subscribe to customer ulinked from an account changes |
conversation | CONVERSATION | Subscribe to conversation changes |
conversation.agent | CONVERSATION | Subscribe to conversation agent changes |
conversation.tags | CONVERSATION | Subscribe to conversation tag changes |
conversation.custom_field | CONVERSATION | Subscribe to conversation custom field changes |
conversation.status | CONVERSATION | Subscribe to conversation status changes |
conversation.priority | CONVERSATION | Subscribe to conversation priority changes |
customer | CUSTOMER | Subscribe to customer changes |
customer.identify | CUSTOMER | Subscribe to customer changes |
customer.created | CUSTOMER | Subscribe to customer changes |
customer.updated | CUSTOMER | Subscribe to customer changes |
customer.custom_fields | CUSTOMER | Subscribe to customer custom field changes |
customer_notes | NOTES | Subscribe to customer notes created/updated event |
customer_notes.deleted | NOTES | Subscribe to customer notes deletion event |
Webhook Security
Webhook requests will contain two headers
which can be used to verify the request's authenticity:
X-Atlas-Webhook-Signature
- the main signaturebase64(HMACSHA256(TIMESTAMP + BODY))
X-Atlas-Webhook-Signature-Timestamp
- the timestamp used to verify the signature
Sign the body and signature timestamp with the webhook secret key using SHA256, then base64 encoding the resulting digest. Represented simply: base64(HMACSHA256(TIMESTAMP + BODY))
To verify the signature, create the same SHA256 HMAC signature and then compare it to the webhook payload to ensure that they match.
Python code that generates the headers
def get_webhook_signature_hash(payload: dict, secret: str, timestamp: float) -> str:
key = secret.encode("ascii")
msg = f"{timestamp}.{payload}".encode("ascii")
return hmac.new(key, msg, hashlib.sha256).hexdigest()
Note - The webhook request body would be of the following shape
{
"event": "customer_notes.deleted",
"data": "{\"id\": \"...\", \"company_id\": \"...\", \"object_type\": \"customer\", \"object_id\": \"...\", \"text\": \"...\", \"created_by\": \"...\", \"created_at\": \"...\", \"updated_at\": \"...\", \"creator\": {...}, \"edited\": false}"
}
To verify the signature, the body has to be used as it is.
ie
payload = {
"event": "customer_notes.deleted",
"data": "{\"id\": \"...\", \"company_id\": \"...\", \"object_type\": \"customer\", \"object_id\": \"...\", \"text\": \"...\", \"created_by\": \"...\", \"created_at\": \"...\", \"updated_at\": \"...\", \"creator\": {...}, \"edited\": false}"
}
timestamp = req.headers.get(X-Atlas-Webhook-Signature-Timestamp)
secret = <unique secret per webhook subscription, available in Atlas App Config>
get_webhook_signature_hash(payload, secret, timestamp)