You can use Webhooks to send company or contact audience data to multiple tools and APIs for which we do not have a native integration yet, such as Zapier, n8n or Clay. The format the data will be shared in is JSON. You can build audiences using relevant signals in Dreamdata and sync them to the outreach tool that you use to create automated workflows to reach out to relevant companies/contacts (enrichment tools may be needed).
Data structure
The data that can be synced for each company consists of:
Company name, domains, country, industry, number of employees
Any of the sync destinations that have the Via Webhooks label can be used with the setup presented below.
How to set up Webhooks?
On Dreamdata's main menu, navigate to Activation Hub -> Syncs and select Webhooks.
Click the Add new button to start creating a Webhook connection.
Choose a title for your sync and desired operation, Insert or Upsert. After the initial sync which includes all existing records, Insert will only sync new contacts/companies. Upsert will also continuously sync all property updates for all contacts/companies. Add the URL for the Webhook you want to use and select the audience (companies or contacts) that you want to sync. Click Save after you filled in the configuration (depending on your setup, you may need to use the HTTP header fields as well).
If you want to test the connection, click the Send data test button after populating the mandatory fields in the configuration. You will receive one company or contact record in the selected Webhook URL.
You will be able to see a list with all your saved Webhook syncs and some properties:In this view, you can disable, enable, edit and delete syncs.
You're all set 🔥 All existing data from the selected audience will be synced immediately. Following each data modeling run, data will be automatically synced daily, for any additions in the selected audience (updates to records already synced are not included).
Zapier
Send audience data to Zapier via Webhooks if you want to use your data in a destination we do not yet support.
Dreamdata integrates with Zapier through Webhooks, allowing you to easily send over audience data. This integration enables you to send audience data to other system that we do not integrate with and trigger workflow automation based on the data received.
Setup required
Login to Zapier
You need an active account
Create a Zap
Use “Webhook by Zapier” as the trigger
Use “Catch Hook” as the trigger event
Find the Webhook URL
Create a Webhook connection in Dreamdata - through the Zapier page or Webhooks
Copy the Webhook URL from Zapier
Paste the URL into the Dreamdata webhook configurator
Test the connection using the “Send data test” button
Save your setup
Clay
Send audience data to Clay via Webhooks.
Dreamdata integrates with Clay through Webhooks, allowing you to easily send over audience data. This integration enables you to enrich your Clay tables with company or contact data collected in Dreamdata and trigger workflow automation based on the data received
Create a Webhook connection in Dreamdata - through the Clay page or Webhooks
Copy the Webhook URL from Clay
Paste the URL into the Dreamdata Webhook configurator
Test the connection using the “Send data test” button
Save your setup
n8n
Send audience data to n8n via Webhooks if you want to use your data in a destination we do not yet support.
Dreamdata integrates with n8n through Webhooks, allowing you to easily send over audience data. This integration enables you to send audience data to other system that we do not integrate with trigger workflow automation based on the data received
Create a Webhook connection in Dreamdata - through the n8n page or Webhooks
Copy the Webhook URL from n8n
Paste the URL into the Dreamdata Webhook configurator
Test the connection using the “Send data test” button
Save your setup
Webhook security
When we send you information (like a message or data), we include a special "signature". Think of this signature like a secret handshake. It proves that the message really came from us and that nobody has changed it on its way to you.
If you do not use any other kind of authentication for your webhooks, we strongly recommend verifying signatures, but verification is optional.
What is a Signature?
Imagine you and your friend have a secret code. When you send a message, you use the secret code to create a special stamp that only you and your friend know how to make.
When your friend receives the message, they can look at the stamp and know two things:
The message is definitely from you (because only you have the secret code).
The message wasn't opened or changed by anyone else.
Our signature works just like that special stamp.
How do we create the signature?
We use a standard method called HMAC (Hash-based Message Authentication Code). It's a fancy name for a process that takes the message and a secret key (that only you and we know) to create the unique signature.
How to Verify the Signature
To make sure the message is authentic, you need to do the same thing we did and see if you get the same signature.
Here are the steps:
Get the message and the signature: When we send you data, we'll send the message itself and the signature as a separate piece of information (usually in the request headers).
Use your secret key: You receive a secret key when you create a webhook in the Dreamdata platform. Keep this safe!
Create your own signature: Use the exact same message data and your secret key to create a new signature using the HMAC method. All common programming languages have libraries to do this.
Compare the signatures: Compare the signature you created with the one you received with the message.
Result:
If they match, you can trust the message is from us and hasn't been tampered with.
If they do not match, you should ignore the message because it might be from an imposter or it might have been changed.
This process ensures that the data you receive is secure and trustworthy.
Example code
Below are a few examples of functions which you can use to validate the signature in different languages.
JavaScript
/** * Verifies an HMAC-SHA256 signature against a received signature, mirroring * the Go signer's logic (HMAC-SHA256, Base64 encoding). * @param {string} secret The secret key. * @param {string} body The raw, utf-8 string request body. * @param {string} receivedSignature The signature received in the request header. * @returns {boolean} True if the signature is valid, false otherwise. */ function verifySignature(secret, body, receivedSignature) { if (!secret) { // If the original signer skipped the signature, we treat it as verified. return true; }
// 1. Calculate the expected signature const hmac = crypto.createHmac('sha256', secret); // Use 'utf8' encoding to match how most webhooks send data and how the // Go function reads the io.Reader body. hmac.update(body, 'utf8');
// 2. Get the Base64 encoded signature const expectedSignature = hmac.digest('base64');
// 3. Compare the signatures securely // We use a timing-safe buffer comparison to prevent potential timing attacks. try { const expectedBuffer = Buffer.from(expectedSignature, 'utf8'); const receivedBuffer = Buffer.from(receivedSignature, 'utf8'); return crypto.timingSafeEqual(expectedBuffer, receivedBuffer); } catch (e) { // Handle cases where the buffers might have different lengths for timingSafeEqual return expectedSignature === receivedSignature; } }
Python
import hmac import hashlib import base64
def verify_signature(secret: str, body: bytes, received_signature: str) -> bool: """ Verifies an HMAC-SHA256 signature against a received signature, matching the Go signer's logic.
:param secret: The secret key (string). :param body: The raw request body (bytes). :param received_signature: The signature received in the request header (string). :return: True if the signature is valid, False otherwise. """ if not secret: # If the original Go signer function skipped the signature, we return True. return True
# 1. Calculate the expected signature (HMAC-SHA256) # key must be bytes, msg must be bytes hashed = hmac.new(key=secret.encode("utf-8"), msg=body, digestmod=hashlib.sha256)
# 2. Get the Base64 encoded signature # b64encode converts to Base64 bytes, then .decode() converts to a string. expected_signature = base64.b64encode(hashed.digest()).decode("utf-8")
# 3. Compare the signatures in a timing-safe manner return hmac.compare_digest(expected_signature, received_signature)
// Setting is a mock struct to hold the secret, mimicking the original Go function's parameter. type Setting struct { Secret string }
// VerifySignature calculates the expected HMAC-SHA256 signature from the body // and compares it against the received signature in a timing-safe manner. func VerifySignature(setting Setting, bodyBytes []byte, receivedSignature string) error { // Skipping verification if no secret is configured (matching the signer's logic) if setting.Secret == "" { return nil }
// Base64 encode the resulting hash bytes expectedSignature := base64.StdEncoding.EncodeToString(hasher.Sum(nil))
// 2. Compare the signatures using ConstantTimeCompare for security expectedBytes := []byte(expectedSignature) receivedBytes := []byte(receivedSignature)
// Check if lengths are equal first to prevent a panic in ConstantTimeCompare if lengths differ if len(expectedBytes) != len(receivedBytes) { return errors.New("signature verification failed: length mismatch") }
// ConstantTimeCompare returns 1 if the two byte slices are equal, 0 otherwise. if subtle.ConstantTimeCompare(expectedBytes, receivedBytes) == 1 { return nil // Signatures match }
return errors.New("signature verification failed: signatures do not match") }