Webhooks

Webhooks let external systems react to activity in an Agility instance — content being published, content being saved, and content moving through workflow. Instead of polling the API, you register a URL that Agility calls when those events happen. The Management SDK exposes webhookMethods so you can list, inspect, create, and remove those registrations programmatically.

JavaScript / TypeScript SDK only. Webhook management is currently available in the JavaScript/TypeScript Management SDK only — the .NET SDK does not include webhook methods. If you are working in .NET, manage webhooks in the Agility UI or call the Management API directly.

Secure delivery, retries and delivery history require @agility/management-sdk 0.1.40 or later.

All of the methods below take the instance guid as their first argument and are available on apiClient.webhookMethods.

List webhooks

Returns the webhooks registered for the instance. Results are paged.

//list the webhooks for the instance
const webhooks = await apiClient.webhookMethods.webhookList(guid);
console.log("Webhooks for Instance:");
console.log(webhooks);

webhookList(guid, take = 20, token = null) — pass the token from the previous result to fetch the next page.

Signing secrets are never returned by webhookList. Use getWebhook to read one, and see the permission note below.

Get a webhook

Retrieves a single webhook by its id.

//get a specific webhook
const webhook = await apiClient.webhookMethods.getWebhook(guid, webhooks[0].id);
console.log("Webhook Details:");
console.log(webhook);

Reading a signing secret requires Full Control. For callers with a lower permission level the secret is masked. The webhook itself is still returned and fully manageable.

Save (create) a webhook

Pass the instance guid and a webhook object. The saved webhook is returned, including its id.

//create a new webhook
const newWebhook = await apiClient.webhookMethods.saveWebhook(guid, {
	name: "My New Webhook",
	url: "https://example.com/webhook",
	contentPublishEvents: true,
	contentSaveEvents: true,
	contentWorkflowEvents: true,
	enabled: true,
	instanceGuid: guid,
});

saveWebhook payload

FieldTypeDescription
namestringDisplay name for the webhook.
urlstringThe endpoint Agility calls when a subscribed event fires.
contentPublishEventsbooleanSubscribe to content publish events.
contentSaveEventsbooleanSubscribe to content save events.
contentWorkflowEventsbooleanSubscribe to content workflow events.
enabledbooleanWhether the webhook is active.
instanceGuidstringThe GUID of the instance the webhook belongs to.
secureDeliveryEnabledbooleanSign every delivery so your endpoint can verify it. Defaults to false. See Verifying Signed Webhooks.
retriesEnabledbooleanRetry a failed delivery. Defaults to false.
retryCountnumberHow many attempts, 1–8. Defaults to 3. Only used when retriesEnabled is true.
retrySpeed"fast" | "standard" | "slow"Base interval between attempts — 30 seconds, 5 minutes or 30 minutes, growing exponentially with jitter.

The server controls the signing secret. Any signingSecret you send is ignored.

Turning on secure delivery

Set secureDeliveryEnabled and save. Agility mints the secret and returns it on that response only, with signingSecretJustCreated: true — store it then, because a later getWebhook will not repeat it as a new value.

//enable secure delivery and capture the minted secret
const saved = await apiClient.webhookMethods.saveWebhook(guid, {
	...webhook,
	secureDeliveryEnabled: true,
});

if (saved.signingSecretJustCreated) {
	console.log("Store this secret:", saved.signingSecret); // whsec_...
}

Get delivery history

Returns delivery attempts for a webhook, newest first. Defaults to the last 7 days; the range cannot exceed 366 days and take maxes out at 100. History is retained for 90 days.

//read the recent delivery history for a webhook
const history = await apiClient.webhookMethods.getWebhookHistory(guid, webhookID, {
	take: 50,
});

for (const attempt of history.items) {
	console.log(attempt.sendDate, attempt.httpResponseCode, attempt.success);
}

//fetch the next page
if (history.token) {
	const next = await apiClient.webhookMethods.getWebhookHistory(guid, webhookID, {
		take: 50,
		token: history.token,
	});
}

getWebhookHistory(guid, webhookID, options?) accepts fromDate, toDate, take and token, and returns a TokenPagedResult<WebhookHistory>items plus a token for the next page.

Useful fields on each entry:

FieldDescription
sendDateWhen the delivery succeeded. Empty while a delivery is still being retried.
successWhether the attempt succeeded.
httpResponseCode / responseTextWhat your endpoint returned. Response text is truncated.
attemptCountAttempts made so far.
nextAttemptUtcWhen the next retry is scheduled, if there is one.
lastErrorThe failure reason for the most recent attempt.
signedWhether the last attempt carried signature headers. null means it has not been attempted yet.
payloadThe body that was sent.

Delivery history is go-forward only. Deliveries from before this feature shipped are not returned, so a webhook you created earlier will show an empty history until it fires again.

Roll a signing secret

Generates a new signing secret immediately and returns it.

//roll the signing secret for a webhook
const rolled = await apiClient.webhookMethods.rotateWebhookSecret(guid, webhookID);
console.log("New secret:", rolled.signingSecret);

For 24 hours afterwards Agility signs each delivery with both the new and the previous secret, sending two space-separated signatures. That gives you a window to deploy the new secret without dropping deliveries. Verification code that accepts any matching signature in the header needs no change at all.

Rolling a secret requires Full Control.

Delete a webhook

Removes a webhook by its id.

//delete a webhook
await apiClient.webhookMethods.deleteWebhook(guid, newWebhook.id);

Deleting a webhook also removes its delivery history.