Introduction

Webhooks are user-defined HTTP callbacks which create notifications by Atlas events to destination systems.

Webhook Topics

TopicCategoryDescription
account.customer.linkedACCOUNTSubscribe to customer linked to an account changes
account.customer.unlinkedACCOUNTSubscribe to customer ulinked from an account changes
conversationCONVERSATIONSubscribe to conversation changes
conversation.agentCONVERSATIONSubscribe to conversation agent changes
conversation.tagsCONVERSATIONSubscribe to conversation tag changes
conversation.custom_fieldCONVERSATIONSubscribe to conversation custom field changes
conversation.statusCONVERSATIONSubscribe to conversation status changes
conversation.priorityCONVERSATIONSubscribe to conversation priority changes
customerCUSTOMERSubscribe to customer changes
customer.identifyCUSTOMERSubscribe to customer changes
customer.createdCUSTOMERSubscribe to customer changes
customer.updatedCUSTOMERSubscribe to customer changes
customer.custom_fieldsCUSTOMERSubscribe to customer custom field changes
customer_notesNOTESSubscribe to customer notes created/updated event
customer_notes.deletedNOTESSubscribe 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 signature which is the hex-encoded HMAC SHA256 hash of {TIMESTAMP}.{PAYLOAD}
  • X-Atlas-Webhook-Timestamp – the float timestamp used to verify the signature

To verify the signature, create the same HMAC SHA256 signature and compare it to the webhook signature header 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("utf-8")
    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 is, before JSON decoding:

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-Timestamp")

secret = "<unique secret per webhook subscription>" # available in Atlas App Config

get_webhook_signature_hash(payload, secret, timestamp)