Data Cleaning and Formatting Enriching Order Data via Subzaps

When raw orders enter your system, the data often needs standardizing before it can be routed to your CRM, project management tools, or email notifications. By combining subzaps, custom code steps, and formatting utilities, you can automatically clean addresses, categorize purchased items, and format text.

flowchart TD
    A["Raw Order Data (Webhook)"] --> B{"Enrichment Routing"}
    
    B --> C["Subzaps"]
    C --> C1["Address & Client Handler"]
    C --> C2["PD Checker"]
    
    B --> D["Code Steps"]
    D --> D1["Line Item Classifier (Python)"]
    D --> D2["Lockbox Cleaner (JS)"]
    
    B --> E["Formatters"]
    E --> E1["Currency & Phone"]
    E --> E2["Timezone Conversion"]
    
    C1 & C2 & D1 & D2 & E1 & E2 --> F["Clean, Standardized Order Data"]

Delegating complex logic to Subzaps

Instead of rebuilding complex address parsing or client deduplication in every workflow, use Subzaps. Subzaps allow you to create a reusable mini-workflow that takes raw inputs, processes them, and returns clean data to your main workflow.

  1. 1

    Add a Delay (Optional)

    If your system occasionally receives duplicate webhooks, add a short delay (e.g., 0.5 minutes) before processing to allow deduplication logic to run.

  2. 2

    Call the Address & Client Handler

    Pass raw location data (Zip, State, City, Street, Unit) and the ClientName to your dedicated Address Subzap. This subzap will return a perfectly formatted address string.

  3. 3

    Call the PD Checker Subzap

    Pass the newly formatted address and the Measurement requirement to your Property Data (PD) Checker Subzap. This ensures you only pull property data scores when necessary for the order type.

Why use Subzaps? If your address formatting rules change in the future, you only need to update the Subzap once, and all parent workflows will automatically inherit the new logic.

Classifying line items with Python

Order line items often come in as a comma-separated string or an array of product names. You can use a Python code step to scan these strings and categorize the order for downstream routing (like flagging an order for "Rush" processing or "Matterport" services).

import re

# Retrieve the line items from the trigger step
items = input_data.get('line_items', '')

output = {
    "Travel": "Travel" if "travel fees" in items.lower() else "",
    "Appraisal": "Appraisal" if "appraisal" in items.lower() else "",
    "Matterport": "Matterport" if "matterport" in items.lower() else "",
    "Amenities": "Yes" if re.search(r'\b(amenity|amenities)\b', items, re.I) else "No",
    "Measurement": "Yes" if any(x in items for x in ["Measurement", "Inspection"]) else "No"
}

# Rush Priority Logic
if any(x in items for x in ["Same Day Rush", "CP-Rush"]):
    output["Rush"] = "Rush"
elif "Morning Rush" in items:
    output["Rush"] = "AMRush"
else:
    output["Rush"] = ""

return output

Standardizing text, numbers, and dates

Raw data rarely arrives in the exact format your database or email templates require. Use built-in formatting utilities to clean up the data before it reaches its final destination.

Data TypeTransformation GoalUtility / MethodExample Output
CurrencyStandardize financial valuesFormat Currency (en_US, ###0.00)149.50
PhoneEnsure dialable numbersFormat Phone Number (Region: US)(555) 123-4567
DatesAlign with local operationsFormat Date/Time (UTC to US/Eastern)2026-10-24
HTMLClean up rich textStrip HTML TagsRemoves `, <b>`, etc.
URLsMake text web-safeReplace & with %26Smith %26 Co

Always convert UTC timestamps to your operational timezone (e.g., US/Eastern) before inserting them into project management tools like Monday.com to prevent scheduling errors.

Handling edge cases

Sometimes data requires highly specific cleanup that standard formatters can't handle. You can use small snippets of code to handle these edge cases gracefully.

Cleaning up Lockbox codes (JavaScript)

Lockbox fields often contain placeholder dashes or messy formatting. This JavaScript snippet ensures you only output valid short codes for display.

// Clean up whitespace and handle nulls
const text = (inputData.rawText || "").trim();

// Define logic conditions
const isDash = text === "-";
const isShortCode = text.length > 0 && text.length <= 5 && !isDash;

// titleDisplay: Only returns if it's a short code (5 chars or fewer)
const titleDisplay = isShortCode ? text : "";

// fullEntry: Returns the original text, unless it's just a dash
const fullEntry = isDash ? "" : text;

return { titleDisplay, fullEntry };
Conditional Property Data (PD) Scores (Python)

If you only want to attach a Property Data score when a measurement is actually ordered, you can use a simple conditional check:

measurement = str(input_data.get('measurement', '')).strip().lower()
raw_pd = input_data.get('pd_score', '')

# Only show PD score if it's a measurement order
if measurement == 'yes':
    final_pd = raw_pd
else:
    # Overwrite with a blank space for non-measurement orders
    final_pd = " " 

return { 'final_pd': final_pd }

Building Subzaps

Learn how to create, configure, and test reusable subzaps for your workspace.