Inspector Toolbelt Help Center
Reference

Webhook Events

Every webhook event, when it fires, and the exact payload it sends.

For advanced users

This page is a technical reference for developers building against ITB webhooks. If you just want to set up a webhook endpoint, start with the Webhooks guide.

The event envelope

Every webhook delivery is an HTTP POST with a JSON body. All events share the same top-level envelope:

FieldTypeDescription
idstringUnique event ID, prefixed evt_ (32 hex characters). Use it as an idempotency key — the same event may be delivered more than once
typestringThe event name, e.g. order.approved
apiVersionstringDate-based payload version. Currently 2026-07-01
createdAtstringWhen the event occurred (ISO 8601)
account.uidstringThe account (owner) ID the event belongs to
account.companyNamestringYour company name, if set
dataobjectSnapshot of the resource the event is about (see per-event sections below)
changesobjectOnly on some events — previous and current snapshots of the fields that changed
{
  "id": "evt_9f2c4b7a1d3e5f60718293a4b5c6d7e8",   // idempotency key
  "type": "order.approved",                        // event name
  "apiVersion": "2026-07-01",
  "createdAt": "2026-07-28T14:30:00.000Z",
  "account": {
    "uid": "abc123",
    "companyName": "Acme Home Services"
  },
  "data": { /* resource snapshot — see below */ },
  "changes": {                                     // only on *.approved, *.completed,
    "previous": { "status": "new" },               // *.status_changed, *.rescheduled
    "current": { "status": "approved" }
  }
}

Each delivery also carries the event name in the webhook-event request header, alongside the signature headers (webhook-id, webhook-timestamp, webhook-signature) described in the Webhooks guide.

Event index

EventFires whenchanges field
order.createdA new Order is created — from the dashboard, the mobile app, or the online scheduling page
order.approvedA Order's status becomes Approved (including one created as approved)status
order.completedA Order's status becomes Completestatus
order.rescheduledThe appointment date/time changes on an Approved OrderappointmentDateTime
order.status_changedFires alongside order.approved and order.completed, and also when an Approved Order moves back to an earlier statusstatus
invoice.paidA Order is marked paid (its paid flag turns true for the first time)
report.publishedA Order first becomes both paid and agreement-signed — the point where its Report is released

Status values in payloads are the raw stored values (draft, new, read, approved, complete, archived) — see Order Statuses.

Field names never change per industry

Payload field names are identical across all industries. For example, the Inspection Type is always sent in a field named inspectionType, whatever your industry calls it on screen.

Order events — data payload

order.created, order.approved, order.completed, order.rescheduled, and order.status_changed all send the same Order snapshot in data:

{
  "id": "req_abc123",                              // order ID
  "status": "approved",                            // see Order Statuses reference
  "appointmentDateTime": "2026-08-01T13:00:00.000Z",
  "inspectionType": "Buyer Inspection",            // your service category name
  "streetAddress": "123 Main St",
  "city": "Springfield",
  "region": "IL",
  "postalCode": "62701",
  "country": "US",
  "timezone": "America/Chicago",
  "contactName": "Jane Buyer",
  "contactEmail": "jane@example.com",
  "contactPhone": "(555) 123-4567",
  "contactType": "client",
  "totalPrice": 450,
  "totalTime": 120,                                // duration in minutes
  "paid": false,
  "agreementSigned": true,
  "assignedInspectors": ["uid1", "uid2"],          // assigned team member IDs
  "requestDateTime": "2026-07-20T09:15:00.000Z",   // when the order was created
  "approvedDateTime": "2026-07-21T10:00:00.000Z",
  "completedDateTime": "2026-08-01T16:30:00.000Z"
}

Date fields are ISO 8601 strings. Any field with no value is omitted from the payload rather than sent as null.

changes per order event

  • order.approvedchanges.previous.status / changes.current.status (current is always "approved")
  • order.completedchanges.previous.status / changes.current.status (current is always "complete")
  • order.status_changedchanges.previous.status / changes.current.status
  • order.rescheduledchanges.previous.appointmentDateTime / changes.current.appointmentDateTime (ISO 8601 strings)
  • order.created — no changes field

Approval fires two events

Approving a Order dispatches both order.approved and order.status_changed; completing one dispatches both order.completed and order.status_changed. Subscribe to one or the other unless you want both deliveries.

invoice.paiddata payload

Fires the first time a Order's paid flag becomes true. The data payload is the same Order snapshot shown above — not an invoice object. There are no invoice-specific fields (no invoice number, amount paid, or payment method); use totalPrice and the paid: true flag, or fetch invoice details from the API. No changes field is sent.

report.publisheddata payload

Fires when a Order first becomes both paid and agreement-signed — the point where its published Report is released to the client. The data payload is the Order snapshot shown above, plus one extra field:

{
  "orderId": "req_abc123",   // same as data.id — the order this report belongs to
  "id": "req_abc123",
  "status": "complete"
  // …all other order snapshot fields
}

No changes field is sent. The payload does not include report URLs.

Events you can subscribe to but that don't fire yet

The endpoint editor also lists order.updated, invoice.created, contact.created, and contact.updated. These event names are reserved and can be selected, but no account activity currently produces them — endpoints subscribed to only these events will not receive deliveries. If they are emitted in the future they will use the standard envelope; their data fields are not yet defined.

Test events — webhook.test

Clicking Test on an endpoint sends a webhook.test event:

{
  "id": "evt_test_5f0e…",        // prefixed evt_test_
  "type": "webhook.test",
  "apiVersion": "2026-07-01",
  "createdAt": "2026-07-28T14:30:00.000Z",
  "account": { "uid": "abc123" },
  "data": {
    "message": "This is a test webhook event.",
    "timestamp": "2026-07-28T14:30:00.000Z"
  }
}

Test events are not signed — they carry an X-Webhook-Test: true header instead of the signature headers. Your receiver should accept them without signature verification (or recognize the header and skip verification for tests only).

Responding to deliveries

  • Respond with any 2xx status within 10 seconds to acknowledge a delivery.
  • 5xx responses and timeouts are treated as temporary — the delivery is retried.
  • Other 4xx responses are treated as permanent — that delivery is not retried.
  • Responding 410 Gone tells ITB to stop sending: the endpoint is disabled immediately.

Endpoint limits, automatic disabling after repeated failures, delivery history, and signature verification are covered in the Webhooks guide.

On this page