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
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
Call the Address & Client Handler
Pass raw location data (
Zip,State,City,Street,Unit) and theClientNameto your dedicated Address Subzap. This subzap will return a perfectly formatted address string. - 3
Call the PD Checker Subzap
Pass the newly formatted address and the
Measurementrequirement 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 outputStandardizing 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 Type | Transformation Goal | Utility / Method | Example Output |
|---|---|---|---|
| Currency | Standardize financial values | Format Currency (en_US, ###0.00) | 149.50 |
| Phone | Ensure dialable numbers | Format Phone Number (Region: US) | (555) 123-4567 |
| Dates | Align with local operations | Format Date/Time (UTC to US/Eastern) | 2026-10-24 |
| HTML | Clean up rich text | Strip HTML Tags | Removes `, <b>`, etc. |
| URLs | Make text web-safe | Replace & with %26 | Smith %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 }