Insites Docs Developers guide IntegrationsRunning Custom Logic from a CRM Field Update

Running Custom Logic from a CRM Field Update

Last updated on June 24, 2026.

Sometimes you want custom server-side functionality to run automatically when an administrator updates a single field on a CRM record in the Insites Instance Admin (IIA), such as a field on a contact profile or on a company. You do not need to build a custom admin screen, and you do not need to poll for changes. The CRM fires a webhook when the record is updated, the webhook calls your endpoint, and your endpoint runs the work.

This is a common and powerful pattern: an administrator changes one field using the native IIA, and that single change drives an entire workflow.

When to use this pattern

  • Issue and email a certificate when an admin sets an assessment status to Passed.
  • Start an onboarding sequence when a contact stage changes.
  • Push an update to a third-party system when a company field changes.
  • Generate a document, send a notification, or update a related record in response to a manual review decision.

How it works

The flow has five steps:

  • An administrator updates a field on a contact or company in the IIA.
  • The CRM fires the webhook (a company update fires the equivalent company webhook).
  • The webhook calls your API endpoint directly. There is no middleware application in between.
  • Your endpoint verifies the request, checks that the field you care about changed, guards against duplicate processing, enqueues a background job, and returns immediately.
  • The background job runs the custom logic: generate a PDF, send an email, call an external API, update a related record, and so on.

Prerequisites

  • CRM module v5.13.1 or later. From this version, profile updates trigger webhooks and the payload supports three modes.
  • Familiarity with Background Jobs and the API.

Webhook payload modes

From CRM v5.13.1 the webhook can send one of three payloads. You choose the mode when you configure the webhook:

  • Changes only: only the fields that changed.
  • Changes with snapshot: the fields that changed, plus the full record. Recommended for this pattern, because you can confirm your field changed and read the rest of the record in a single call.
  • Full object (default): the entire record, with no indication of what changed.

Step 1: Choose the trigger field

Decide which field an admin will update to start the workflow. This can be an existing CRM profile field or one you add to the schema. Use a clear, dedicated field, for example a status field whose value an admin sets to Passed.

Step 2: Configure the CRM webhook

Point a CRM webhook at the endpoint you build in step 3, and set the mode to Changes with snapshot. The webhook fires on contact updates (or company updates).

Step 3: Build the webhook receiver endpoint

Create a POST page that receives the webhook. It verifies the signature, checks the field, guards against duplicate processing, enqueues a background job, and returns 200 quickly. Keep all logic in commands and background jobs; the page is only a controller.

app/views/pages/webhooks/contact-updated.json.liquid

---
slug: webhooks/contact-updated
method: post
---
{% liquid
  assign payload = context.params

  # confirm the request came from the CRM (compare a signature against a shared secret)
  assign secret = context.constants.WEBHOOK_SECRET

  # only act when the field we care about changed to Passed
  assign new_status = payload.changes.level2_review_status

  if new_status == 'Passed'
    background source_name: 'issue_certificate', max_attempts: 3, contact_id: payload.snapshot.id, level: 2
      function _ = 'lib/commands/certificates/issue', contact_id: payload.snapshot.id, level: 2
    endbackground
  endif

  response_status 200
%}

The exact payload keys depend on the webhook mode you select. Inspect a sample delivery to confirm the field paths before relying on them.

Step 4: Run the work in a background job

The background job calls a command that performs the work. Because the job runs asynchronously, the webhook request returns straight away while the slow work (PDF generation, email, external API calls) happens in the background, with automatic retries on failure.

Important considerations

Make it idempotent

The update webhook fires on every change to the record, not only the change you care about. Always guard the work so it runs once. For example, before issuing a certificate, check that one has not already been issued for that contact. The field changing is necessary but not sufficient; already done is the real stop condition.

Return quickly

Verify and enqueue, then return 200. Do not do slow work inside the request. Offload it to a background job.

Avoid loops

If your background job updates the same record, make sure it cannot re-trigger the same workflow. The idempotency guard above handles this.

Verify the source

Check the request against a shared secret stored in before acting on it.

Related

Have a suggestion for this page?

Didn't quite find what you are looking for or have feedback on how we can make the content better then we would love to hear from you. Please provide us feedback and we will get back to you shortly.