ClarifyClarify APIBeta
Guides

Build a workflow

Automate actions with code workflows

Code workflows let you run JavaScript when records change — validate fields, update related records, send notifications, or sync data.

How workflows work

  1. A record is added to a list (trigger)
  2. Clarify runs your JavaScript code block
  3. Your code reads the record, makes decisions, and writes back via the API

Your code receives an input object with:

  • input.record — the record that triggered the workflow
  • input.diff — array of field changes, each with op, path, val, and oldVal
  • input.actor — who/what made the change
  • input.workspace — your workspace slug
  • process.env.CLARIFY_API_KEY — your workspace API key (available as an env var)

Example: validate required fields on stage change

This workflow checks that required fields are filled when a deal moves to "Closed Won", and reverts the stage if they're not:

var record = input.record;
var diff = input.diff;

// Skip if triggered by another workflow (prevent loops)
if (input.actor.source_id === "workflow" || input.actor.entity === "api_key") {
  return;
}

// Only run when stage changes to Closed Won
if (record.stage !== "Closed Won") {
  return;
}

var errors = [];
if (!record.amount) errors.push("Amount is required");
if (!record.close_date) errors.push("Close date is required");
if (!record.company_id) errors.push("Company is required");

if (errors.length > 0) {
  // Find the old stage value from the diff array
  var stageChange = diff.find(function(d) { return d.path === "stage"; });
  var oldStage = stageChange ? stageChange.oldVal : "Negotiation";

  await fetch(
    "https://api.clarify.ai/v1/workspaces/" + input.workspace + "/objects/deal/records",
    {
      method: "PATCH",
      headers: {
        "Authorization": "api-key " + process.env.CLARIFY_API_KEY,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        data: [{
          id: record._id,
          type: "deal",
          attributes: {
            stage: oldStage,
            validation_error_notes: errors.join(", ")
          }
        }]
      })
    }
  );
}

Key patterns

Loop guard

Every workflow that writes data must check the actor to prevent infinite loops:

if (input.actor.source_id === "workflow" || input.actor.entity === "api_key") {
  return;
}

Fetching the full record

The trigger payload may not include all fields. Fetch the full record if you need fields beyond what's in the diff:

var res = await fetch(
  "https://api.clarify.ai/v1/workspaces/" + input.workspace + "/objects/deal/records/" + record._id,
  {
    headers: { "Authorization": "api-key " + process.env.CLARIFY_API_KEY }
  }
);
var full = await res.json();
var deal = full.data.attributes;

Writing validation errors

Instead of creating tasks, write plain-language errors to a text field on the record. Customers prefer this pattern:

// Write error to a text field on the record
{ validation_error_notes: "Amount and close date are required" }

// Clear on success
{ validation_error_notes: "" }

Tips

  • Use var instead of const/let for broader compatibility in the runtime
  • Test with a single record before enabling for your full pipeline
  • Workflows trigger on list membership — make sure your list filter matches the right records