Webhooks

Webhooks

SendPromptly delivers outbound webhooks as HTTP POST requests to customer endpoints. Each webhook is signed, traced, and retried on failure.

Headers included with every webhook

  • X-SP-Event-Key: event name (e.g. user.signup)
  • X-SP-Message-Id: unique message ULID
  • X-SP-Timestamp: unix timestamp of send
  • X-SP-Signature: v1=<hex_hmac_sha256> — HMAC-SHA256 over the string {timestamp}.{body} using the endpoint secret
  1. Extract X-SP-Timestamp and X-SP-Signature from headers.
  2. Reject if the timestamp is older/newer than 5 minutes (prevent replay).
  3. Recreate signedContent = "{timestamp}.{raw_body}".
  4. Compute expected HMAC-SHA256 using your webhook secret and hex-encode.
  5. Use a constant-time comparison (hash_equals) to compare the expected value with the v1= signature.

Example header: X-SP-Signature: v1=0123ab...

Delivery semantics & retries

  • Success is strictly 2xx responses only; any non-2xx triggers a retry.
  • Timeout for webhook delivery attempts is 30 seconds.
  • Retry schedule (MVP): 5 attempts total at 0s, +1m, +10m, +1h, +6h.
  • Retries do not increment tenant usage; usage is counted once on first successful delivery per delivery_run.

Security & SSRF protections

  • Webhook endpoints must use HTTPS; non-TLS endpoints are rejected.
  • The portal performs DNS/IP checks to prevent SSRF; endpoints are validated at create time and before each send.

Operations

  • Rotate signing secret in the Webhook Endpoints screen; the portal stores secrets encrypted.
  • Use the portal’s Test Webhook button to exercise an endpoint and view attempts.
  • Message details show delivery runs and attempt logs with failure reasons and timestamps.

Example verification pseudo-code

# timestamp = request.headers['X-SP-Timestamp']
# signature = request.headers['X-SP-Signature']  # e.g. "v1=<hex>"
# body = raw_request_body
# signed = f"{timestamp}.{body}"
# expected = HMAC_SHA256(secret, signed)  # hex
# if not hash_equals(expected, signature_after_parsing): reject

Link to: API ingestion quickstart and portal Webhook Endpoints UI for setup steps and examples.