Webhooks allow you to register custom callbacks that will be called with an HTTP POST request whenever something changes in Ardoq. Webhooks must be enabled by Ardoq for your organization: email us or reach out via chat to request access.
Note: You must be an admin in Ardoq to create webhooks.
Getting Started
Once enabled, you can find the webhooks settings by going to the main menu and selecting Preferences > Organization settings > Settings and navigating to the Webhooks tab.
Select Create Webhook and enter your a name and a destination URL for the webhook to POST to.
You can test your webhook by making a small change in your components like adding and removing a tag.
Important: What the Endpoint Receives
A webhook's URL receives data for every change across your entire organization. It cannot be limited to specific workspaces, and payloads are not filtered by permissions, so the endpoint receives all change data, including confidential fields. Only use an endpoint you trust.
Request Format
Here's an example POST request made by a webhook:
{
"resource-type": "tag",
"resource-id": "cf73fa1e257fdb6a576540e9",
"event-type": "create",
"organization": "a8574eb78e6293348cae2d0f",
"organization-label": "usertesting",
"data": {
"description": "",
"last-updated": "2024-10-17T10:54:46.427Z",
"_id": "cf73fa1e257fdb6a576540e9",
"lastModifiedBy": "b28b7a30f64d1642e2b8595a",
"ardoq-persistent": null,
"createdBy": "b28b7a30f64d1642e2b8595a",
"lastModifiedByName": "John G",
"name": "Test-tag",
"createdByEmail": "test@ardoq.com",
"created": "2024-10-17T10:54:46.427Z",
"rootWorkspace": "48114aeb3832a02710bf8f41",
"references": [],
"components": [
"e0a1be808bc264be4ed3fd2c"
],
"created-by": "b28b7a30f64d1642e2b8595a",
"last-modified-by": "b28b7a30f64d1642e2b8595a",
"lastUpdated": "2024-10-17T10:54:46.427Z",
"origin": null,
"lastModifiedByEmail": "test@ardoq.com",
"_version": 1,
"ardoq": {
"entity-type": "tag"
},
"createdByName": "John G"
}
}Signing Your Webhooks
What Signing Does
Signing is optional, but highly recommended. When you turn it on, Ardoq adds a signature to every request it sends. Your receiving system can then verify that signature to confirm two things: the request genuinely came from Ardoq, and nobody altered it in transit.
Verifying the signature on your end is also optional but recommended. Ardoq adding the signature doesn't require your system to do anything, deliveries still arrive whether or not you verify them. Verification is a check you choose to add on your side, and we strongly recommend it.
You can turn signing on when creating a webhook, or add it to an existing one at any time.
What Changes When a Webhook is Signed
Turning on signing changes the webhook's behavior in three ways:
Requests are signed with HMAC-SHA256 (see "Verifying signatures" below).
The event set narrows. A signed webhook delivers only component, reference, and tag changes. Unsigned webhooks continue to deliver the broader set (including field, report, dashboard, and survey changes). If you rely on those broader events, keep the webhook unsigned, or use a separate unsigned webhook for them.
HTTPS is required and verified. A signed webhook must use an HTTPS URL, and Ardoq verifies the endpoint's TLS certificate. Unsigned webhooks are not required to use HTTPS, and Ardoq does not verify their certificate.
Adding a signing secret to an existing webhook is one-way. To remove signing, delete the webhook and create a new unsigned one.
Adding a Signing Secret
When creating a webhook: the signing option is on by default. Leave it on to create a signed webhook.
Later: open the webhook's menu and select Add signing secret. Signing requires an HTTPS URL, so if the webhook uses HTTP, create a new one using HTTPS.
The secret is shown once, at the moment it's created. Copy it and store it somewhere safe. Ardoq will never show it again.
Rotating the secret
If a secret is lost or may be compromised, open the webhook's menu and select Rotate signing secret. The current secret stops working immediately and a new one is shown once. Update your receiving endpoint with the new secret right away, or it won't be able to verify requests.
Verifying Signatures
Ardoq signs each request with two headers:
X-Ardoq-Signature-256: sha256=<hex digest>X-Ardoq-Timestamp: <unix epoch seconds>
To verify a request:
Read the
X-Ardoq-TimestampandX-Ardoq-Signature-256headers.Reject the delivery if the timestamp is outside your tolerance window. The examples below use 5 minutes; pick a budget that covers network transit plus clock skew.
Compute HMAC-SHA256(secret, "<timestamp>.<raw body>"), hex-encode it, and prefix sha256=.
Compare your result to
X-Ardoq-Signature-256using a constant-time comparison.
Use the raw request body exactly as received. Parsing and reserializing the JSON changes the bytes and breaks verification.
Example Verification — Python
import hashlib, hmac, time
# Reject deliveries older than five minutes, so a captured request cannot be
# replayed later. The timestamp is signed, so it cannot be swapped for a fresh
# one. Pick your own budget: it must cover network transit plus clock skew.
TOLERANCE_SECONDS = 300
def verify_signature(body: bytes, signature: str, timestamp: str, secret: str)
-> bool:
if not signature or not timestamp.isdigit():
return False
if abs(time.time() - int(timestamp)) > TOLERANCE_SECONDS:
return False
expected = "sha256=" + hmac.new(
secret.encode(), timestamp.encode() + b"." + body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Example Verification — Node.js
const crypto = require('node:crypto');
const TOLERANCE_SECONDS = 300;
const verifySignature = (body, signature, timestamp, secret) => {
if (!signature || !/^\d+$/.test(timestamp)) return false;
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > TOLERANCE_SECONDS) return false;
const expected =
'sha256=' +
crypto.createHmac('sha256', secret).update(timestamp + '.').update(body).digest('hex');
const a = Buffer.from(expected);
const b = Buffer.from(signature);
return a.length === b.length && crypto.timingSafeEqual(a, b);
};
module.exports = { verifySignature };
Example Verification — Java
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public final class VerifyWebhook {
private static final long TOLERANCE_SECONDS = 300;
public static boolean verifySignature(byte[] body, String signature, String timestamp, String secret)
throws Exception {
if (signature == null || timestamp == null || !timestamp.matches("\\d+")) return false;
long sentAt = Long.parseLong(timestamp);
if (Math.abs(System.currentTimeMillis() / 1000 - sentAt) > TOLERANCE_SECONDS) return false;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
mac.update((timestamp + ".").getBytes(StandardCharsets.UTF_8));
byte[] digest = mac.doFinal(body);
StringBuilder expected = new StringBuilder("sha256=");
for (byte b : digest) expected.append(String.format("%02x", b));
// MessageDigest.isEqual is constant-time; String.equals is not.
return MessageDigest.isEqual(
expected.toString().getBytes(StandardCharsets.UTF_8),
signature.getBytes(StandardCharsets.UTF_8));
}
}
FAQ
What ports are allowed for egress traffic, and why is port 443 recommended?
It is recommended to use port 443 to ensure traffic is sent over an encrypted channel, enhancing data security.
Do webhooks support deletion events?
Webhooks do not support deletion events.
Can I remove signing from a webhook?
No. Signing is one-way. To stop signing, delete the webhook and create a new unsigned one.
Why did my signed webhook stop sending report or dashboard events?
Signed webhooks deliver only component, reference, and tag changes. If you need the broader event set, use an unsigned webhook.
Why can't I add a signing secret to my webhook?
Signing requires an HTTPS URL. Create a new webhook with an HTTPS URL to enable signing.
