Performance Insights
API task

Receive report webhooks and verify the signature (API)

Register an HTTPS webhook with POST /api/v1/customers/me/webhook, read the dump_id and status it receives, verify the HMAC signature, handle retries.

Published 2026-11-10 by PerformanceInsights.ai

Short answer: Send POST /api/v1/customers/me/webhook with a full-scope API key and a body of {"url": "https://...", "secret": "..."}. DumpTriage then sends a signed POST to that HTTPS URL each time a dump's report is delivered or its analysis fails for good. Check the X-Triage-Signature HMAC over the timestamp and the raw body, answer with a 2xx, and fetch the report when you need it. DELETE on the same path stops it.

1. Register the endpoint

curl -X POST https://api.performanceinsights.ai/api/v1/customers/me/webhook \
  -H "Authorization: Bearer dts_..." \
  -H "Content-Type: application/json" \
  -d '{"url": "https://hooks.example.com/dumptriage", "secret": "a-long-random-string-you-keep"}'

The key must have full scope: an upload-scoped key gets 403. url must be an https address that resolves only to public IP addresses. secret is 16 to 256 characters of your choosing; keep it, because it is never returned. The response is {"registered": true}. One webhook per account: registering again replaces the URL and secret. GET /api/v1/customers/me shows the current webhook_url, never the secret.

To stop deliveries, call DELETE /api/v1/customers/me/webhook. It returns 204 and clears the URL and the secret. Email notifications are not affected.

2. What arrives

POST /dumptriage HTTP/1.1
Content-Type: application/json
X-Triage-Timestamp: 1789761600
X-Triage-Signature: sha256=<hex>

{"dump_id":"<uuid>","report_url":"<portal page for this dump>","status":"delivered"}
FieldMeaning
dump_idThe id that POST /api/v1/dumps returned. Fetch the report with GET /api/v1/dumps/{id}/report.
statusdelivered: the report is ready. failed: the analysis failed for good.
report_urlThe portal page for this dump, the same link the upload response returns. It opens for anyone signed in to the account.
connector_group_urlOnly on a dump that came in through a crash-platform connector: that platform's own link back to the crash group.

3. Verify the signature

The signature is the HMAC-SHA256 of the timestamp, a literal . and the raw body bytes, keyed with your secret. Use the bytes exactly as received: do not parse and re-serialize the JSON. Compare in constant time and reject a timestamp more than five minutes old, so a captured delivery cannot be replayed later.

import hashlib, hmac, time

def verify(secret: str, headers, raw_body: bytes) -> bool:
    ts = headers["X-Triage-Timestamp"]
    if abs(time.time() - int(ts)) > 300:
        return False
    expected = "sha256=" + hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, headers["X-Triage-Signature"])

4. Answers, retries and limits

Errors on these calls

StatusWhen
400The url is not accepted: not https, no host, or it resolves to a non-public address (on register).
401Missing or invalid API key.
403The key's scope or the account does not allow it, for example an upload-scoped key.
422Missing url or secret, or a secret outside 16 to 256 characters.

Every error body is {"detail": "..."}.

Common questions

Which URLs can I register as a webhook?
An https URL that resolves only to public addresses. http URLs, hosts that resolve to private or internal addresses, and redirects are not accepted; the address is checked again at every delivery.
What does DumpTriage send to my webhook?
A POST with a JSON body of dump_id, status (delivered or failed) and report_url, signed with your secret in the X-Triage-Timestamp and X-Triage-Signature headers. A dump that came in through a crash-platform connector also carries connector_group_url.
What happens if my endpoint is down?
A delivery that does not get a 2xx answer within 20 seconds is retried with exponential backoff: 30 seconds after the first failure, doubling up to one hour, for up to 12 attempts by default. After that the delivery is dropped; the report is still available through the API and the portal.

Ready to send a dump?

Upload a minidump to DumpTriage. It runs the debugger, reads the output and sends back the faulting module, the stack and a plain-language root cause (how the analysis works). Except on the Solo plan, cases the automated passes can't settle go to an engineer. Free during the pilot.

Create an account