Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.morf.health/docs/llms.txt

Use this file to discover all available pages before exploring further.

This doc is for anyone configuring actions that send data to third-party tools like HubSpot, Healthie, or an email. These expressions control what gets sent — formatting names, dates, URLs, and other fields into what your team needs. To check out our existing destinations, see our Integrations page.

Build a display name from profile fields

Use this when you’re sending a patient’s name to a CRM and want it properly formatted — for example, as a HubSpot deal name or contact display name. Combine first and last name into a single formatted string. Start here — simple first + last name:
get_current_property_value("first_name").optFlatMap(firstName,
  get_current_property_value("last_name").optMap(lastName,
    titleCase(string(firstName)) + " " + titleCase(string(lastName))
  )
)
With a label suffix (e.g. for a HubSpot deal name):
get_current_property_value("first_name").optFlatMap(firstName,
  get_current_property_value("last_name").optMap(lastName,
    titleCase(string(firstName)) + " " + titleCase(string(lastName)) + " Intake"
  )
)
Advanced — with city and state:
get_current_property_value("first_name").optFlatMap(firstName,
  get_current_property_value("last_name").optFlatMap(lastName,
    get_current_property_value("us_mailing_address").?city.optFlatMap(city,
      get_current_property_value("us_mailing_address").?state.optMap(state,
        titleCase(string(firstName)) + " " + titleCase(string(lastName)) + " " +
        titleCase(string(city)) + ", " + titleCase(string(state)) + " Intake"
      )
    )
  )
)
titleCase() automatically capitalizes names correctly — so “jane smith” becomes “Jane Smith” regardless of how the patient typed it.
Use these sample prompts with Flo to generate a CEL expression that fits your goals.
Build a deal name from the patient's first name, last name, city, and state.
Combine first and last name into a single display name with title casing.

Format a date for display or integration input

Use this when you need to send a date to a third-party tool and it needs to be in a specific format — like showing a birthday in an email or setting a HubSpot close date. Many integrations (like HubSpot) require dates in specific formats. Use these expressions to convert stored dates. Start here — format a date for display in an email (MM/DD/YYYY):
get_current_property_value("date_of_birth").optMap(d, formatDateUSStyle(d)).orValue("")
Advanced — convert a future date to milliseconds for HubSpot:
parseTimestamp(
  morf_event_time.add(parseDuration("720h")).getDateString() + "T00:00:00Z"
).getMilliseconds()
Annotated breakdown:
parseTimestamp(                                          // Parse the string back into a timestamp
  morf_event_time.add(parseDuration("720h"))            // Add 30 days (720h) to the event time
    .getDateString()                                     // Get just the date portion (YYYY-MM-DD)
  + "T00:00:00Z"                                        // Anchor to midnight UTC
).getMilliseconds()                                     // Convert to milliseconds for HubSpot
HubSpot date fields need a number, not a date string. If you’re writing to a HubSpot date property, make sure to add .getMilliseconds() at the end — otherwise HubSpot won’t accept the value.
Use these sample prompts with Flo to generate a CEL expression that fits your goals.
Set the HubSpot close date to 30 days from now.
Format the patient's date of birth for display in an email.

Build a URL with a profile ID

Use this when you want to send a patient a personalized link — like a pre-filled intake form — that includes their unique ID. Append a patient’s integration-specific ID to a base URL to generate a personalized link. Template:
"[BASE URL]" + morf_profile_ids.[integration].id
Examples:
"https://your-form-url.io/to/abc123?_id=" + morf_profile_ids.feathery.id

"https://your-app.io/intake?form_id=" + morf_profile_ids.feathery.id
Replace feathery with the integration name that holds the ID you need (e.g. healthie, hubspot). Check the profile IDs available in your event payload to see which ones are populated.

Format a mailing address

Use this when you need to pass a patient’s full address to a CRM or other tool as a single field. Combine address line 1 and line 2 into a single string, with a fallback to just line 1 if line 2 is empty. Example output: 123 Main St, Apt 4B
get_current_property_value("us_mailing_address").?address_1.optFlatMap(address_1,
  get_current_property_value("us_mailing_address").?address_2.optMap(address_2,
    address_1 + ", " + address_2
  )
).or(
  get_current_property_value("us_mailing_address").?address_1
)
Annotated breakdown:
get_current_property_value("us_mailing_address").?address_1   // Get address line 1
  .optFlatMap(address_1,                                       // If present, try to get line 2
    get_current_property_value("us_mailing_address").?address_2
      .optMap(address_2, address_1 + ", " + address_2)        // Combine both lines
  )
.or(                                                           // Fallback: just line 1 if no line 2
  get_current_property_value("us_mailing_address").?address_1
)

Invert or remap a value

Use this when you need to flip a value before sending it — for example, converting an internal code into a human-readable label, or reversing a yes/no answer. Transform one value into another — for example, flipping a boolean string, or mapping an internal code to a display label. Show “Yes” or “No” instead of “true” or “false”:
answers.?consented_to_treatment.optMap(val,
  val == 'true' ? 'Yes' : 'No'
)
Show a readable label instead of an internal code (e.g. “cash_pay” → “Self Pay”):
answers.?insurance_type.optMap(val,
  val == 'cash_pay' ? 'Self Pay' : val
)
Use these sample prompts with Flo to generate a CEL expression that fits your goals.
If the patient answered 'true' for is_day_time_patient, output 'No', otherwise output 'Yes'.
Map the internal value 'cash_pay' to the label 'Self Pay' before sending to HubSpot.
If the patient's status is 'active', output 'Enrolled', otherwise output 'Not Enrolled'.

Access nested object fields

Use this when a profile property holds a complex object — like an insurance record or address — and you need to pull out one specific field from inside it. When a property stores a nested object (like an insurance record or address), navigate into it with .?field. Template:
get_current_property_value("[PROPERTY]").?[NESTED FIELD]
Examples:
get_current_property_value("primary_insurance").?payer_name

get_current_property_value("us_mailing_address").?city

get_current_property_value("us_mailing_address").?state
With a fallback if the field is empty:
get_current_property_value("primary_insurance").?payer_name.orValue("unknown")
Use .?field not .field when navigating nested objects. The ? tells Morf to handle the case where the field might be missing. Without it, the workflow may fail if the nested field isn’t there.

Access the first item in a list

Use this when a field returns multiple values — like a multi-select answer or a list of associated records — and you only need the first one. When a field contains a list, use [0] to get the first item. Get the first selected value from a multi-select answer:
answers.?Language_selector[0]
Get the ID of the first associated record:
associated_deals[0].id
If the list might be empty, ask Flo to add a safety check — otherwise the expression may fail if there’s nothing in the list.

Build a computed identifier from multiple fields

Use this when you need to generate a unique value — like an email address or reference key — by combining several fields together. Construct a synthetic value (like an email or reference key) by concatenating multiple fields. Generate a unique email from name and DOB:
properties[?"firstName"].optFlatMap(firstName,
  properties[?"lastName"].optFlatMap(lastName,
    properties[?"client_dob"].optMap(dob,
      firstName + lastName + dob + "@yourorg.io"
    )
  )
)
Generate a unique company name with a random suffix:
get_current_property_value("last_name").value() + " Fam " + randomNumbers(3)
randomNumbers(3) adds a random 3-digit number at the end — useful when you need records to be unique but don’t have a better identifier available.

Ready to build?

Open the Dashboard

Start building your workflow now.

Talk to the Morf team

Want a walkthrough or help getting started? Book a demo with us.

Further reading

For the complete CEL function reference — including all available operators, string functions, date helpers, and optional chaining syntax — see the CEL Reference.