API Reference
Webhook Events
HTTP headers
- Content-Type
application/jsonAll webhook payloads are JSON-encoded.
- X-Checkupstream-Signature
<64 lowercase hex characters>HMAC-SHA256 of the raw request body using your webhook secret, with no algorithm prefix. Included only when a secret is configured. Verify the signature before processing the event.
Verifying signatures
X-Checkupstream-Signature header before processing events. The value is an HMAC-SHA256 hash of the raw request body, hex-encoded with no algorithm prefix.import crypto from "node:crypto";
export function verifySignature(
body: string,
signature: string,
secret: string,
): boolean {
// Check the format before decoding untrusted header values.
if (!/^[0-9a-f]{64}$/i.test(signature)) return false;
const expected = crypto.createHmac("sha256", secret).update(body).digest();
return crypto.timingSafeEqual(Buffer.from(signature, "hex"), expected);
}Event payloads
incident.detected
Sent when a vendor declares an active incident, outside maintenance, on a service your organization tracks. For a service scoped to certain components, the vendor must name one of them. impact is the vendor's own label, passed through unaltered; it never decides whether we send.
{
"event": "incident.detected",
"rule": "vendor_incident",
"serviceId": "svc_stripe",
"serviceName": "Stripe",
"incidentId": "inc_abc123",
"title": "Elevated error rates on the Charges API",
"impact": "major_outage",
"componentNote": "Vendor named components: Charges API",
"sdkFailures": null,
"affectedProjects": [
{
"id": "prj_checkout",
"name": "checkout-api",
"dependencies": [
{ "name": "stripe", "version": "14.12.0", "ecosystem": "npm" }
]
}
],
"failedLookups": [],
"enrichment": {
"aiSummary": "Card charges are failing for a subset of requests.",
"affectedCapabilities": ["Card payments"],
"survivingCapabilities": ["Subscription billing"],
"mitigations": ["Queue charge retries behind an idempotency key"],
"architectureInsight": null,
"affectedProjects": [
{
"id": "prj_checkout",
"name": "checkout-api",
"dependencies": [
{ "name": "stripe", "version": "14.12.0", "ecosystem": "npm" }
]
}
],
"affectedRegions": ["us-east-1"],
"recurrenceCount7d": 2,
"source": "ai-cached"
},
"timestamp": "2026-04-06T14:32:00Z"
}sdk.failures
Sent when your own SDK's calls to a vendor fail: at least 5% of at least 20 calls in a five-minute window returned a 5xx response, a network error or a timeout. 4xx responses are not counted. sdkFailures.threshold carries the values that applied. One alert covers consecutive failing windows.
{
"event": "sdk.failures",
"rule": "sdk_failures",
"serviceId": "svc_stripe",
"serviceName": "Stripe",
"incidentId": "",
"title": "38 of 412 calls to api.stripe.com failed (5xx/timeouts), 14:05–14:10 UTC, from your SDK",
"impact": "",
"componentNote": null,
"sdkFailures": {
"hostnames": ["api.stripe.com"],
"failedCalls": 38,
"totalCalls": 412,
"windowStart": "2026-04-06T14:05:00.000Z",
"windowEnd": "2026-04-06T14:10:00.000Z",
"threshold": { "failureRatio": 0.05, "minCalls": 20 }
},
"affectedProjects": [],
"failedLookups": [],
"enrichment": {
"aiSummary": null,
"affectedCapabilities": [],
"survivingCapabilities": [],
"mitigations": [],
"architectureInsight": null,
"affectedProjects": [],
"affectedRegions": [],
"recurrenceCount7d": null,
"source": "structural-only"
},
"timestamp": "2026-04-06T14:16:00Z"
}incident.updated
Sent after a status or severity change to the original webhook URL, while its channel is enabled and the alert remains unmuted. Read impact for the current severity and updateBody for the vendor's update.
{
"event": "incident.updated",
"kind": "incident_updated",
"serviceId": "svc_stripe",
"serviceName": "Stripe",
"incidentId": "inc_abc123",
"title": "Elevated error rates on the Charges API",
"status": "monitoring",
"impact": "degraded",
"updateBody": "We are monitoring the results of a fix.",
"timestamp": "2026-04-06T15:02:00Z"
}incident.resolved
Sent when a tracked record closes, to the original webhook URL while its channel is enabled and the alert remains unmuted. Read resolution before interpreting the event as vendor recovery.
- vendor_declared
- The vendor explicitly reported its incident resolved. Application recovery still needs your own evidence.
- absent_from_feed
- The incident disappeared from the vendor feed. No vendor resolution was recorded.
- unspecified
- The record closed without a recognized reason. Vendor recovery is unconfirmed.
The duration field is a human-readable interval between the record’s start and closure timestamps, such as 42m. It is not measured application downtime.
{
"event": "incident.resolved",
"kind": "incident_resolved",
"serviceId": "svc_stripe",
"serviceName": "Stripe",
"incidentId": "inc_abc123",
"title": "Elevated error rates on the Charges API",
"resolution": "absent_from_feed",
"duration": "42m",
"timestamp": "2026-04-06T15:14:00Z"
}alert.test
Sent when you press "Send test" on a webhook channel in Settings → Alerts. If a secret is configured, the test uses it to sign the request. Use this event to check your receiver before an incident.
{
"event": "alert.test",
"service": "Stripe",
"title": "Test alert from CheckUpstream",
"timestamp": "2026-04-06T14:32:00Z"
}Ready to receive events
Add your endpoint and secret, then use Send test to check signature handling and delivery.