StatusDashboard
Webhooks

Inbound Webhooks

Create or update events from signed inbound HTTP requests.

View Markdown

Inbound webhooks let external systems create and update incident events on your status dashboards without manual entry in the admin console. Monitoring tools, CI pipelines, and incident platforms send signed HTTPS POST requests; StatusDashboard validates the signature and queues the payload for processing.

Create signing keys on Inbound webhooks. The sections below cover authentication, trigger and update payloads, idempotency, code examples, and webhook logs.


Endpoint

Inbound webhooks let external tools automatically open and update incident events on your StatusDashboard pages. No polling, no manual entry, and no third-party integration middleware required.

Inbound webhooks support incidents only. Maintenance windows and informational notices should be created via the REST API or the admin console.
MethodEndpoint
POSThttps://api.statusdashboard.com/public/webhooks/inbound

Authentication

Every request must include a valid signing key. Signing keys are created on Inbound webhooks. Each key has a Key ID and a Signing Secret.

The signing secret is shown exactly once when the key is created. Store it securely in your secrets manager — it cannot be retrieved after the creation dialog is closed.

Request headers

HeaderValue
Content-Typeapplication/json
X-SD-Key-IdYour signing key ID (e.g. wk_a1b2c3d4e5f6a7b8)
X-SD-SignatureHMAC-SHA256 signature (see format below)

Signature format

The X-SD-Signature header must be formatted as:

t=<unix_timestamp>,v1=<hmac_hex>

Where:

  • <unix_timestamp> is the current Unix timestamp in seconds (e.g. 1712345678)
  • <hmac_hex> is an HMAC-SHA256 hex digest computed over the string <unix_timestamp>.<raw_request_body>, using your signing secret as the key

StatusDashboard validates the signature and rejects requests with a timestamp older than 5 minutes to prevent replay attacks.

All authentication failures return 200 { "ok": true }. This is intentional — returning 4xx on auth failure would allow an attacker to enumerate whether a Key ID exists. If events aren't appearing, verify that the Key ID and signing secret match what is shown in the dashboard.

Payload reference

The request body must be a JSON object. The action field determines which operation is performed.

Trigger action — create a new incident

Use action: "trigger" to open a new incident event.

FieldTypeRequiredDescription
action"trigger"YesIdentifies this as a trigger operation
titlestringYesIncident title (1–250 characters)
descriptionstringYesIncident description (1–5000 characters)
impactAnalysisstringNoOptional customer and service impact details. Rich text field. See Rich text fields. Max 5,000 characters.
severitystringYesEvent-level severity label (must match a configured severity, e.g. "Major Outage"). Applied uniformly to every component in componentIds.
componentIdsstring[]YesUUIDs of the affected components (1–20 IDs). Obtain IDs from GET /app/components.
statusLabelstringNoWorkflow phase label to start at (e.g. "Investigating"). Defaults to the first non-final incident phase.
initialMessagestringNoFirst timeline message (1–5000 characters). Defaults to "Incident opened via inbound webhook." when omitted.
idempotencyKeystringNoOptional dedupe key for this trigger (1–128 characters). Prevents duplicate incidents when your tool retries the same delivery. See Avoiding duplicate incidents below.
notificationsbooleanNoWhether to send subscriber email notifications when the incident is created. Defaults to true.
segmentNotificationobjectNoTarget notifications to specific subscriber segments. Requires the segments feature on your plan.
segmentNotification.enabledbooleanWhen true, applies segment filtering to notification recipients.
segmentNotification.mode"include" | "exclude"include sends only to subscribers in the selected segments; exclude suppresses them.
segmentNotification.segmentIdsstring[] (UUID)Segment IDs from GET /app/segments. At least one required when enabled is true and mode is include.
attributesarrayNoCustom key/value attributes on the event (max count per plan). Each item: { "key": string, "value": string, "isPublic": boolean }.
Unlike event creation via the admin console or REST API, inbound webhooks use a single severity for the whole incident. That severity is applied to every listed component — you cannot assign a different severity per component in one webhook payload.
segmentNotification requires the segments feature. If your plan does not include segments, requests that include this field fail with a processing_failed webhook log outcome.

Update action — advance an existing incident

Use action: "update" to add a timeline entry and advance the workflow phase of an existing incident.

impactAnalysis is not accepted on update actions. Set it on trigger, or use PATCH /app/events/{id} to change it later.

FieldTypeRequiredDescription
action"update"YesIdentifies this as an update operation
eventIdstring (UUID)YesThe ID of the event to update
statusLabelstringYesThe workflow phase label to advance to (e.g. "Resolved")
messagestringYesThe timeline message for this update (1–5000 characters)
notificationsbooleanNoUpdate whether future notifications are sent for this event.
segmentNotificationobjectNoUpdate segment notification targeting (same shape as trigger). Requires the segments feature.
attributesarrayNoReplace event attributes (same shape as trigger).

Status updates always enqueue a timeline notification when notifications is true on the event after processing.

Response

StatusMeaning
200Request queued for processing (also returned for authentication failures — see note above). Check webhook logs for the final processed or processing_failed outcome.
400Invalid request body — malformed JSON or schema validation error
429Rate limit exceeded — slow down your request rate

Rate limiting

Each org has a configurable inbound webhook rate limit (requests per minute). If the limit is reached, the server returns 429. The rate limit only applies after authentication succeeds, so a 429 confirms that the Key ID and signature were valid.

Avoiding duplicate incidents

Monitoring tools and scripts often retry webhook requests when a connection times out or the response is slow. A 200 response means your request was queued, not that the incident already exists — so retries can accidentally open the same incident more than once if you do not deduplicate on your side.

For action: "trigger", you can send an optional idempotency key so repeated deliveries with the same key reuse the original incident instead of creating another one.

How to send itExample
JSON field (recommended)"idempotencyKey": "pagerduty-incident-48291"
Request headerX-SD-Idempotency-Key: pagerduty-incident-48291

Use a value that uniquely identifies the specific outage or alert — for example your monitoring system's incident ID, or a hash of the alert fingerprint. If you omit a key, each accepted trigger creates a new incident (same as today).

Good practices:

  • Generate a new key for each distinct incident; do not reuse a generic label like "api-down" across unrelated outages.
  • Include the key in the signed JSON body so it is covered by your HMAC signature.
  • If the body field and header are both sent, they must match.

Keys are remembered for 3 days, then expire automatically. After that window, the same key can open a new incident if you send it again.

Idempotency applies to trigger (create) only. Update requests are not deduplicated — use the eventId from your first successful trigger when sending timeline updates.

Code examples

Store your Key ID and Signing Secret in environment variables — never hard-code credentials.

Beyond the required fields, you may optionally include notifications, segmentNotification, and attributes on both trigger and update payloads. Omit any you do not need — defaults apply (notifications defaults to true on trigger).

# Required fields only
BODY='{"action":"trigger","title":"Database high latency","description":"Queries taking >5s","severity":"Major Outage","componentIds":["b2c3d4e5-f6a7-8901-bcde-f12345678901"]}'

# Or include optional notification, segment, and attribute fields:
# BODY='{"action":"trigger","title":"Database high latency","description":"Queries taking >5s","severity":"Major Outage","componentIds":["b2c3d4e5-f6a7-8901-bcde-f12345678901"],"notifications":true,"segmentNotification":{"enabled":true,"mode":"include","segmentIds":["<segment-uuid>"]},"attributes":[{"key":"runbook_url","value":"https://wiki.example.com/db-latency","isPublic":true}]}'

TS=$(date +%s)
SIG=$(echo -n "${TS}.${BODY}" | openssl dgst -sha256 -hmac "$SD_SIGNING_SECRET" | awk '{print $2}')

curl -X POST https://api.statusdashboard.com/public/webhooks/inbound \
  -H "Content-Type: application/json" \
  -H "X-SD-Key-Id: $SD_KEY_ID" \
  -H "X-SD-Signature: t=${TS},v1=${SIG}" \
  -d "$BODY"

Webhook logs

StatusDashboard records an entry for every authenticated inbound webhook request. Logs appear below the signing keys on the inbound webhooks page (10 entries per page; use Prev/Next to browse older entries).

What is logged

OutcomeWhen
acceptedThe payload passed schema validation and was queued for async processing
processedThe worker successfully created or updated an incident
processing_failedThe payload was valid JSON but failed semantic validation (unknown severity, component, or workflow phase; plan limits; non-incident update; etc.)
rate_limitedAuthentication succeeded but the org rate limit was exceeded
validation_failedAuthentication succeeded but the payload failed JSON parsing or schema validation

Authentication failures (bad Key ID, bad signature, stale timestamp) are not logged — the Key ID must be valid and the signature must pass before a log entry is written.

A 200 { "ok": true } response means the request was queued, not that an event was created. Always check webhook logs for the terminal processed or processing_failed outcome.

Log details

Each log entry shows:

  • Outcomeaccepted, processed, processing_failed, rate_limited, or validation_failed
  • Action — the action field from the payload (e.g. trigger, update), or unknown if the payload could not be parsed
  • Key ID — which signing key was used
  • Received at — timestamp of the request
  • Reason — for failures, a short description of why processing failed
  • Event ID — present on processed outcomes; links to the created or updated incident
  • Payload — the raw request body, up to 16 KB

Click any log row to open the detail view, which shows the full parsed payload and a copy button.

If a payload exceeds 16 KB, it is truncated at that boundary and the detail view displays a warning. Outcomes reflect the full, untruncated payload — truncation only affects what is stored for inspection.

Retention

Webhook logs are retained for 30 days and then automatically deleted. They are not part of your audit log.

On this page

We use cookies

We use essential cookies to keep the site working, and optional analytics cookies to understand how it's used. Read our Privacy Policy.