Using Webhooks to Keep External Applications Up-to-Date
Webhooks are a powerful way to receive real-time notifications from Coalesce Quality when specific events occur. This allows external applications to stay updated without constant polling, saving resources and ensuring timely updates.Introduction to Webhooks
Coalesce Quality sends HTTP POST requests to a predefined URL whenever certain events occur, including issue lifecycle changes, incident notifications, or a simple ping to confirm that the webhook endpoint is reachable. Webhooks are defined by a schema that ensures the correct data structure is maintained. Each event has a specific payload format, allowing external applications to process the data accordingly. Latest schema definition is available as a JSON Schema and as HTML documentation.Key Concepts
- Event Types: Webhook events can represent different actions, such as
ping,issue_created,issue_updated,issue_status_updated,issue_closed,incident_open,incident_closed, andincident_cancelled. - Payload Structure: Each event payload adheres to a defined JSON schema, ensuring consistency and reliability in the data received.
- Callback Mechanisms: Webhooks can trigger specific commands or actions in the receiving application, making it possible to automate workflows based on incoming events.
Webhook Event Schema
The webhook event schema defines the structure of the payload sent for each event type:workspace: Identifies the workspace where the event occurred.event_id: A unique identifier for the event.event_time: The time when the event occurred, formatted as a date-time string.event_type: One of the specific event types (ping,issue_created,issue_updated,issue_status_updated,issue_closed,incident_open,incident_closed,incident_cancelled), each with its own structured payload.callbacks: An array of callbacks that can be invoked based on the event, containing details such asurl,action_name, and associatedissues_command.
Event Types
Issue Events
- Issue Created: Notifies that a new issue has been created. Contains an
IssueSummarywith details such asissue_id,title,description,status, trigger and affected entities. - Issue Updated: Indicates that an existing issue has been updated.
- Issue Status Updated: Signals that the status of an issue has changed (e.g., investigating, expected, fixed, no action needed).
- Issue Closed: Signals that an issue has been closed.
Incident Events
- Incident Open: Notifies that a new incident has been opened. Contains an
IncidentSummarywithincident_id,title,description, andincident_url. - Incident Closed: Indicates that an incident has been closed.
- Incident Cancelled: Signals that an incident has been cancelled.
Other Events
- Ping: A simple test event sent during webhook setup to confirm the endpoint is functional. Payload contains a
message.
Working with Webhook Events
To start using webhooks:- Register a Webhook Endpoint: Provide a URL endpoint where Coalesce Quality can send events. Use Settings > Integrations > Add integration > Webhook.
- Handle Incoming Events: Set up your server to process incoming POST requests. Ensure that your endpoint correctly interprets the payload format defined in the webhook event schema. Return 2xx status codes to confirm receipt.
- Verify the Signature (recommended): Confirm each request genuinely came from Coalesce Quality before acting on it. See Verifying Webhook Signatures.
- Automate Actions: Use the event data to trigger specific actions in your application, such as updating a database, notifying users, or calling other APIs.
Custom request headers
You can attach custom HTTP headers to every webhook request under Settings > Integrations > your webhook integration — for example anAuthorization header so Coalesce Quality can reach a protected endpoint.
Mark a header secret to store its value securely instead of in the plaintext configuration: secret header values are write-only — masked in the UI and API responses and never returned — and are sent only in the outgoing request. Non-secret headers keep a visible, editable value. To change a secret header enter a new value; leave it blank to keep the stored one.
For authenticating that a request genuinely came from Coalesce Quality, prefer signature verification over a static token in a custom header.
Verifying Webhook Signatures
Every webhook delivery is signed so your endpoint can verify that the request genuinely originated from Coalesce Quality and was not tampered with or replayed. Verification is strongly recommended — it is the most robust way to authenticate incoming webhooks (stronger than a static bearer token in a custom header).Signing secret
Each webhook integration has its own signing secret, generated by Coalesce Quality. The secret is shown once, at the moment it is generated — when you create the webhook integration and when you rotate it. Copy it then and store it somewhere secure; it is not retrievable afterwards. The value is prefixed withwhsec_; use the entire string, including the prefix, as the HMAC key.
If you lose the secret, rotate it (Settings > Integrations > your webhook integration) to obtain a fresh one.
Rotating without downtime: when you rotate, the previous secret stays valid for a 24-hour grace window. During that window every delivery is signed with both the new and previous secrets (two values in X-Coalesce-Signature), so your endpoint keeps verifying whether it holds the old or the new secret. Update your endpoint to the new secret any time within the window.
Signature headers
Two headers are sent on every request:| Header | Description |
|---|---|
X-Coalesce-Timestamp | Unix timestamp (seconds) of when the delivery was signed. |
X-Coalesce-Signature | One or more space-separated, scheme-prefixed signatures — e.g. v1=<hex> or, during a rotation grace window, v1=<hex-new> v1=<hex-old>. A request is authentic if any v1= value matches. The v1= prefix identifies the signature scheme. |
Signature scheme
Each signature is a hex-encoded HMAC-SHA256 computed over the timestamp and the raw request body, joined by a.:
- Read the
X-Coalesce-Timestampheader and the raw request body (verify before any JSON parsing or re-serialization — a re-serialized body will not match). - Recompute the signature with your copy of the signing secret and check it against each
v1=value inX-Coalesce-Signatureusing a constant-time comparison; accept the request if any matches. - Optionally reject requests whose timestamp is outside your tolerance window. Retries reuse the original signing timestamp, so allow for the retry backoff window (deliveries may be retried for up to ~30 minutes).