Skip to main content

Webhooks

Receive real-time event notifications from Ascent at your own HTTPS endpoints. When something happens in your organization — a ticket is created, an invoice is paid — Ascent sends a signed HTTP POST to the URLs you register, so you can integrate Ascent with your own applications and workflows.

Overview

The Webhooks integration lets you:

  • Register one or more endpoint URLs and choose which events each one receives
  • Verify every delivery with a per-endpoint signing secret (HMAC-SHA256)
  • Send a test event to confirm your receiver works
  • Inspect a delivery history with per-attempt status and HTTP response codes
  • Enable/disable or delete an endpoint at any time — disabled and deleted endpoints stop receiving events immediately
  • Rely on automatic retries with exponential backoff, and a dead-letter state for deliveries that never succeed

Webhooks are an Enterprise feature. The entire integration requires a license that includes the webhooks feature — on plans without it, the Webhooks endpoints are unavailable (including read-only views). The management UI is available to Owners and Admins (and any role granted the Integrations: Manage permission).

Go to Settings and open the Webhooks tab. Click Add Endpoint, enter your receiver URL, choose the events to subscribe to, and save. The signing secret is shown once at creation time — copy it then, because it is never displayed again.

Subscribable events

EventFires when
ticket.createdA ticket is created
ticket.updatedA ticket is updated
ticket.resolvedA ticket transitions to a closed/resolved status
invoice.createdAn invoice is created
invoice.paidAn invoice is fully paid
client.createdA client is created

A webhook.test event is also sent when you use Send test event; it is not a subscribable type.

Request format

Each delivery is an HTTP POST with a JSON body and these headers:

HeaderDescription
Content-Typeapplication/json
X-Ascent-EventThe event type (e.g. ticket.created)
X-Ascent-DeliveryThe unique delivery id (useful for receiver-side de-duplication)
X-Ascent-SignatureThe signature: t=<unix-seconds>,v1=<hex HMAC-SHA256>

The JSON body has the shape:

{
"event": "ticket.created",
"createdAt": "2026-06-15T04:00:00.000Z",
"data": { "id": "ckv...", "ticketNumber": 2606150001, "subject": "Server offline", "clientId": "ckc..." }
}

The data object varies by event type and contains identifiers and a few summary fields for the affected entity.

Verifying the signature

The X-Ascent-Signature header binds a timestamp into the signature so you can reject replayed or tampered payloads. To verify:

  1. Parse the t (timestamp) and v1 (signature) values from the header.
  2. Build the signed message as "{t}.{raw request body}" — use the raw body bytes, exactly as received, before any JSON re-serialization.
  3. Compute HMAC-SHA256(signing_secret, signed_message) and hex-encode it.
  4. Compare it to v1 using a constant-time comparison.
  5. Optionally reject the delivery if t is older than your tolerance (e.g. 5 minutes) to guard against replays.
// Node.js (Express) example
import crypto from 'node:crypto';

function verifyAscentSignature(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const expected = crypto
.createHmac('sha256', secret)
.update(`${parts.t}.${rawBody}`)
.digest('hex');
const a = Buffer.from(expected);
const b = Buffer.from(parts.v1 ?? '');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Deliveries, retries, and dead-lettering

Ascent considers a delivery successful on any 2xx response. A non-2xx response, a connection error, or a timeout (deliveries abort after 10 seconds) is a failure. Failed deliveries are retried with exponential backoff (roughly 1m → 5m → 30m → 2h), up to 5 attempts. A delivery that still fails after the final attempt is marked dead-letter and is not retried further.

The delivery history for each endpoint (the clock icon in the Webhooks tab) lists recent deliveries with their event type, status (PENDING / DELIVERING / DELIVERED / FAILED / DEAD_LETTER), the HTTP response code of the last attempt, and the attempt count.

Disabling an endpoint (the Enabled toggle) or deleting it stops new events from being queued, and any in-flight delivery to a now-inactive endpoint is abandoned rather than retried.

Endpoint URL requirements

To protect internal infrastructure, endpoint URLs must be public http(s) URLs. Ascent rejects URLs that target loopback, link-local (including cloud metadata 169.254.169.254), or private IP ranges, and *.internal / *.local hostnames.

Rotating a secret

If a signing secret is exposed, rotate it. Rotation issues a new secret (shown once) and immediately invalidates the old one, so update your receiver promptly to avoid failed verifications.

Permissions

CapabilityRequirement
View endpoints and delivery historyIntegrations: Read
Create, edit, delete, test, or rotate endpointsIntegrations: Manage (granted to Owner and Admin roles by default)
Use the Webhooks integration at all (view, create, edit, delete, test, rotate)The organization's plan must include the webhooks feature (Enterprise). On plans without it, every Webhooks request — including read-only views — is rejected.