Agent skill

Simpro Webhooks Skill

Receive and verify Simpro webhooks. Use when setting up a Simpro webhook subscription endpoint, verifying the X-Response-Signature header (HMAC-SHA1 hex of the raw body), debugging Simpro signature verification failures, or handling events like job.created, company.customer.updated, invoice.created, quote.updated, and employee.deleted.

Install this skill

npx skills add hookdeck/webhook-skills --skill simpro-webhooks


When to Use This Skill

  • How do I receive Simpro webhooks?
  • How do I verify the Simpro X-Response-Signature header?
  • Why does my Simpro webhook signature verification fail?
  • How do I handle job.created, company.customer.updated, or invoice.created events?
  • How do I use the Simpro "Test Subscription" button (test.updated)?

Setup note

Set the Secret on the Simpro webhook subscription to a long random value, then paste the same value here.

Verification (core)

Simpro sends X-Response-Signature: the lowercase hex HMAC-SHA1 of the raw request body, keyed with the UTF-8 bytes of the subscription's Secret. No prefix, no timestamp. Return 401 when the header is missing or wrong. There is no timestamp, so there is no replay protection beyond HTTPS; de-duplicate on your side.

const crypto = require('crypto');

function verifySimproSignature(rawBody, signature, secret) {
  // Exactly 40 hex chars: Buffer.from(x, 'hex') silently truncates invalid hex
  if (!signature || !secret || !/^[0-9a-fA-F]{40}$/.test(signature)) return false;
  const expected = crypto.createHmac('sha1', secret).update(rawBody).digest();
  return crypto.timingSafeEqual(Buffer.from(signature, 'hex'), expected);
}

Python: hmac.compare_digest(signature.lower(), hmac.new(secret.encode(), raw_body, hashlib.sha1).hexdigest()).

Read the raw body (express.raw({ type: '*/*' })) and parse JSON only after the check.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Common Event Types

Every message is a POST with a JSON body {ID, build, description, name, action, reference, date_triggered}. Dispatch on ID; reference holds the ids to fetch the record from the Simpro API.

IDDescription
job.createdA job was created
company.customer.updatedA company customer was updated
invoice.createdAn invoice was created
quote.updatedA quote was updated
employee.deletedAn employee was deleted
test.updatedSent by Test Subscription

The available events are chosen in the subscription screen; see references/overview.md.

Important Headers

HeaderDescription
X-Response-SignatureHex HMAC-SHA1 of the raw body

Environment Variables

SIMPRO_WEBHOOK_SECRET=your_subscription_secret   # System > Setup > API > Webhook Subscriptions > Secret

Local Development

# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 simpro --path /webhooks/simpro

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 9, 2026

View on GitHub →