Agent skill

Jobber Webhooks Skill

Receive and verify Jobber webhooks. Use when setting up Jobber app webhook handlers, debugging X-Jobber-Hmac-SHA256 signature verification, or handling field service topics like CLIENT_CREATE, INVOICE_UPDATE, APP_CONNECT, and APP_DISCONNECT.

Install this skill

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


When to Use This Skill

  • How do I receive Jobber webhooks?
  • How do I verify the X-Jobber-Hmac-SHA256 header?
  • Why is my Jobber webhook signature verification failing?
  • How do I handle CLIENT_CREATE, INVOICE_UPDATE, APP_CONNECT, or APP_DISCONNECT webhooks?
  • How do I fetch the changed object from a Jobber webhook payload?

Jobber webhooks are for app developers: they are configured per app in the Jobber Developer Center, not in an end-user Jobber account.

Verification (core)

Jobber sends X-Jobber-Hmac-SHA256: the base64 HMAC-SHA256 of the raw request body, keyed with your app's OAuth client secret. There is no timestamp or webhook ID in the signed content. Capture the raw body before JSON parsing, and compare the base64 strings in constant time (no base64 decoding of the header).

Node:

const crypto = require('crypto');

function verifyJobberSignature(rawBody, signatureHeader, clientSecret) {
  if (!signatureHeader || !clientSecret) return false;
  const expected = Buffer.from(
    crypto.createHmac('sha256', clientSecret).update(rawBody).digest('base64'), 'utf8');
  const received = Buffer.from(String(signatureHeader), 'utf8');
  if (received.length !== expected.length) return false; // timingSafeEqual throws otherwise
  return crypto.timingSafeEqual(received, expected);
}

Python:

import hmac, hashlib, base64

def verify_jobber_signature(raw_body: bytes, signature_header: str | None, client_secret: str) -> bool:
    if not signature_header or not client_secret:
        return False
    expected = base64.b64encode(hmac.new(client_secret.encode(), raw_body, hashlib.sha256).digest())
    # Encode both sides to bytes: a non-ASCII header gives False (401), not a TypeError (500)
    return hmac.compare_digest(signature_header.encode("utf-8"), expected)

Jobber does not ship a webhook verification SDK, so verify manually. In Express, read the body with express.raw({ type: '*/*' }) so any content type verifies.

For complete handlers with route wiring, event dispatch, and tests, see:

Payload Structure

Jobber payloads are thin: they say what happened, not the object itself. Query the Jobber GraphQL API with itemId to get the details.

{
  "data": {
    "webHookEvent": {
      "topic": "CLIENT_CREATE",
      "appId": "3ef22a50-072d-430c-a78f-b7646657560b",
      "accountId": "MQ==",
      "itemId": "MQ==",
      "occurredAt": "2026-07-16T16:31:31-06:00"
    }
  }
}

Dispatch on data.webHookEvent.topic. Delivery is at-least-once and some actions fire the same topic twice in about a second, so handle duplicates idempotently. Respond within 1 second and process asynchronously.

Common Event Types

Topics follow the pattern OBJECT_ACTION and are values of WebHookTopicEnum in the Jobber GraphQL schema (the Developer Center lists all of them when you add a webhook).

TopicTriggered When
CLIENT_CREATEA client is created (needs the client read scope)
INVOICE_UPDATEAn invoice changes, e.g. a payment is applied or the status changes
APP_CONNECTAn account connects your app
APP_DISCONNECTAn account disconnects your app (handling is required for Marketplace apps)

For the full reference, see Jobber's webhook documentation.

Environment Variables

JOBBER_CLIENT_SECRET=your_jobber_oauth_client_secret   # Your app's OAuth client secret

Hookdeck Setup

Jobber signs webhooks with your app's OAuth client secret. When you create a Jobber source in Hookdeck, paste that secret there so Hookdeck verifies X-Jobber-Hmac-SHA256 before forwarding. Then set the Hookdeck source URL as the webhook URL for your app in the Jobber Developer Center. See references/setup.md.

Local Development

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

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 6, 2026

View on GitHub →