{
  "format": "revenanas.clay-workflow/v1",
  "name": "Revenanas Library - HubSpot Lead Routing",
  "slug": "hubspot-clay-lead-routing",
  "description": "Preserve existing HubSpot owners, derive territory and segment, select an eligible rep by capacity-adjusted load, and emit a reviewable writeback payload.",
  "source": {
    "builder": "Clay official Terracotta CLI",
    "workspace_type": "Revenanas enterprise test",
    "workflow_id": "wf_0tl6yfh3eKNNfTApfdZ",
    "last_tested": "2026-09-11",
    "published": false
  },
  "verification": {
    "graph_valid": true,
    "data_credits_used": 0,
    "action_credits_used": 0,
    "passing_run_ids": [
      "wfr_0tl6ze4QneDvgCtN4wV",
      "wfr_0tl6zvyiEz9zRDVFzb5",
      "wfr_0tl6ze4vmqJfxorj9hC"
    ],
    "observed_platform_constraints": [
      "Code-node output schemas only accepted primitive field types; the rep roster is serialized as JSON between code nodes.",
      "The standalone code tester allowed datetime, but the workflow runtime did not; write timestamps belong in the destination action.",
      "Mapped optional inputs require an explicit JSON Schema required list or empty strings may be treated as missing."
    ]
  },
  "trigger": {
    "key": "trigger",
    "spec": {
      "triggerType": "manual",
      "inputSchema": {
        "type": "object",
        "required": [
          "hubspot_record_id",
          "email",
          "country",
          "employee_count",
          "reps"
        ],
        "properties": {
          "hubspot_record_id": {
            "type": "string",
            "description": "HubSpot contact or lead record ID"
          },
          "email": {
            "type": "string",
            "description": "Lead email address"
          },
          "company_domain": {
            "type": "string",
            "description": "Company domain, when known"
          },
          "existing_owner_id": {
            "type": "string",
            "description": "Current HubSpot owner ID; leave empty for an unowned lead"
          },
          "country": {
            "type": "string",
            "description": "ISO country code used to derive territory"
          },
          "employee_count": {
            "type": "number",
            "description": "Employee count used to derive segment"
          },
          "target_account": {
            "type": "boolean",
            "description": "Whether the company is a named target account"
          },
          "reps": {
            "type": "array",
            "description": "Current eligible-rep roster and capacity data",
            "items": {
              "type": "object"
            }
          }
        }
      }
    }
  },
  "nodes": [
    {
      "key": "normalize",
      "spec": {
        "nodeType": "code",
        "name": "Normalize lead and derive routing keys",
        "code": "import json\n\nEUROPE = {\"BE\", \"BG\", \"CZ\", \"DK\", \"EE\", \"ES\", \"FI\", \"FR\", \"GR\", \"HR\", \"HU\", \"IS\", \"IT\", \"LT\", \"LU\", \"LV\", \"NL\", \"NO\", \"PL\", \"PT\", \"RO\", \"SE\", \"SI\", \"SK\"}\n\ndef handler(context):\n    country = (context.get_input(\"country\") or \"\").strip().upper()\n    employee_count = int(context.get_input(\"employee_count\") or 0)\n    existing_owner_id = (context.get_input(\"existing_owner_id\") or \"\").strip()\n    target_account = bool(context.get_input(\"target_account\") or False)\n    if country in {\"US\", \"CA\"}:\n        region = \"North America\"\n    elif country in {\"GB\", \"IE\"}:\n        region = \"UKI\"\n    elif country in {\"DE\", \"AT\", \"CH\"}:\n        region = \"DACH\"\n    elif country in EUROPE:\n        region = \"Rest of Europe\"\n    else:\n        region = \"Unknown\"\n    if target_account:\n        segment = \"Named account\"\n    elif employee_count >= 1000:\n        segment = \"Enterprise\"\n    elif employee_count >= 200:\n        segment = \"Mid-market\"\n    elif employee_count > 0:\n        segment = \"SMB\"\n    else:\n        segment = \"Unknown\"\n    route_status = \"held_existing_owner\" if existing_owner_id else \"ready_for_routing\"\n    return {\"hubspot_record_id\": str(context.get_input(\"hubspot_record_id\") or \"\").strip(), \"email\": (context.get_input(\"email\") or \"\").strip().lower(), \"company_domain\": (context.get_input(\"company_domain\") or \"\").strip().lower(), \"existing_owner_id\": existing_owner_id, \"country\": country, \"employee_count\": employee_count, \"target_account\": target_account, \"region\": region, \"segment\": segment, \"route_status\": route_status, \"reps_json\": json.dumps(context.get_input(\"reps\") or [])}",
        "inputSchema": {
          "type": "object",
          "required": [
            "hubspot_record_id",
            "email",
            "country",
            "employee_count",
            "reps"
          ],
          "properties": {
            "hubspot_record_id": {
              "type": "string",
              "sourceNodeId": "{{trigger}}",
              "sourcePath": "$.hubspot_record_id"
            },
            "email": {
              "type": "string",
              "sourceNodeId": "{{trigger}}",
              "sourcePath": "$.email"
            },
            "company_domain": {
              "type": "string",
              "sourceNodeId": "{{trigger}}",
              "sourcePath": "$.company_domain"
            },
            "existing_owner_id": {
              "type": "string",
              "sourceNodeId": "{{trigger}}",
              "sourcePath": "$.existing_owner_id"
            },
            "country": {
              "type": "string",
              "sourceNodeId": "{{trigger}}",
              "sourcePath": "$.country"
            },
            "employee_count": {
              "type": "number",
              "sourceNodeId": "{{trigger}}",
              "sourcePath": "$.employee_count"
            },
            "target_account": {
              "type": "boolean",
              "sourceNodeId": "{{trigger}}",
              "sourcePath": "$.target_account"
            },
            "reps": {
              "type": "array",
              "items": {
                "type": "object"
              },
              "sourceNodeId": "{{trigger}}",
              "sourcePath": "$.reps"
            }
          }
        },
        "outputSchema": {
          "hubspot_record_id": {
            "type": "string",
            "description": "Normalized HubSpot record ID"
          },
          "email": {
            "type": "string",
            "description": "Normalized lead email"
          },
          "company_domain": {
            "type": "string",
            "description": "Normalized company domain"
          },
          "existing_owner_id": {
            "type": "string",
            "description": "Current owner ID or an empty string"
          },
          "country": {
            "type": "string",
            "description": "Normalized ISO country code"
          },
          "employee_count": {
            "type": "number",
            "description": "Employee count used by segmentation"
          },
          "target_account": {
            "type": "boolean",
            "description": "Whether the lead belongs to a named account"
          },
          "region": {
            "type": "string",
            "description": "Derived routing territory"
          },
          "segment": {
            "type": "string",
            "description": "Derived commercial segment"
          },
          "route_status": {
            "type": "string",
            "description": "Existing-owner guard result"
          },
          "reps_json": {
            "type": "string",
            "description": "Rep roster serialized as JSON for the selection step"
          }
        },
        "incomingEdges": [
          {
            "sourceNode": "{{trigger}}"
          }
        ]
      }
    },
    {
      "key": "owner_guard",
      "spec": {
        "nodeType": "conditional",
        "name": "Does HubSpot already have an owner?",
        "inputSchema": {
          "route_status": {
            "type": "string",
            "sourceNodeId": "{{normalize}}",
            "sourcePath": "$.route_status"
          }
        },
        "conditionalMode": "rules",
        "rulesConditionalConfig": {
          "rules": [
            {
              "id": "existing_owner",
              "name": "Existing owner",
              "condition": {
                "type": "GroupOp",
                "combinationMode": "And",
                "items": [
                  {
                    "type": "BinOp",
                    "dataPath": [
                      "route_status"
                    ],
                    "operator": "Equal",
                    "value": "held_existing_owner"
                  }
                ]
              }
            }
          ]
        },
        "incomingEdges": [
          {
            "sourceNode": "{{normalize}}"
          }
        ]
      }
    },
    {
      "key": "hold_existing_owner",
      "spec": {
        "nodeType": "code",
        "name": "Hold lead with existing owner",
        "code": "def handler(context):\n    owner_id = context.get_input(\"existing_owner_id\") or \"\"\n    return {\"hubspot_record_id\": context.get_input(\"hubspot_record_id\") or \"\", \"assigned_owner_id\": owner_id, \"routing_status\": \"held_existing_owner\", \"routing_reason\": \"Existing HubSpot owner preserved; automatic reassignment was blocked.\"}",
        "inputSchema": {
          "hubspot_record_id": {
            "type": "string",
            "sourceNodeId": "{{normalize}}",
            "sourcePath": "$.hubspot_record_id"
          },
          "existing_owner_id": {
            "type": "string",
            "sourceNodeId": "{{normalize}}",
            "sourcePath": "$.existing_owner_id"
          }
        },
        "outputSchema": {
          "hubspot_record_id": {
            "type": "string",
            "description": "HubSpot record held by the guard"
          },
          "assigned_owner_id": {
            "type": "string",
            "description": "Existing HubSpot owner that was preserved"
          },
          "routing_status": {
            "type": "string",
            "description": "Held-existing-owner terminal status"
          },
          "routing_reason": {
            "type": "string",
            "description": "Explanation of why reassignment was blocked"
          }
        },
        "incomingEdges": [
          {
            "sourceNode": "{{owner_guard}}",
            "ruleId": "existing_owner"
          }
        ]
      }
    },
    {
      "key": "select_rep",
      "spec": {
        "nodeType": "code",
        "name": "Select eligible rep by capacity",
        "code": "import json\n\ndef _truthy(value):\n    if isinstance(value, bool):\n        return value\n    return str(value or \"\").strip().lower() in {\"1\", \"true\", \"yes\", \"y\"}\n\ndef _values(value):\n    if isinstance(value, list):\n        return {str(item).strip() for item in value}\n    return {item.strip() for item in str(value or \"\").split(\",\") if item.strip()}\n\ndef handler(context):\n    region = (context.get_input(\"region\") or \"Unknown\").strip()\n    segment = (context.get_input(\"segment\") or \"Unknown\").strip()\n    reps = json.loads(context.get_input(\"reps_json\") or \"[]\")\n    eligible = []\n    for rep in reps:\n        owner_id = str(rep.get(\"hubspot_owner_id\") or \"\").strip()\n        regions = _values(rep.get(\"regions\"))\n        segments = _values(rep.get(\"segments\"))\n        if not _truthy(rep.get(\"active\")) or _truthy(rep.get(\"out_of_office\")) or not owner_id:\n            continue\n        if region not in regions and \"All\" not in regions:\n            continue\n        if segment not in segments and \"All\" not in segments:\n            continue\n        current_load = max(float(rep.get(\"current_open_leads\") or 0), 0)\n        capacity_weight = max(float(rep.get(\"capacity_weight\") or 1), 0.1)\n        eligible.append((current_load / capacity_weight, str(rep.get(\"email\") or \"\").lower(), owner_id))\n    if not eligible:\n        return {\"assigned_owner_id\": \"\", \"assigned_owner_email\": \"\", \"routing_reason\": f\"No active, available {region} / {segment} rep has a HubSpot owner ID.\", \"routing_status\": \"held_no_eligible_rep\", \"eligible_rep_count\": 0, \"selection_score\": 0}\n    eligible.sort(key=lambda item: (item[0], item[1], item[2]))\n    selection_score, email, owner_id = eligible[0]\n    return {\"assigned_owner_id\": owner_id, \"assigned_owner_email\": email, \"routing_reason\": f\"Selected lowest capacity-adjusted load among {len(eligible)} active {region} / {segment} reps.\", \"routing_status\": \"assigned\", \"eligible_rep_count\": len(eligible), \"selection_score\": selection_score}",
        "inputSchema": {
          "region": {
            "type": "string",
            "sourceNodeId": "{{normalize}}",
            "sourcePath": "$.region"
          },
          "segment": {
            "type": "string",
            "sourceNodeId": "{{normalize}}",
            "sourcePath": "$.segment"
          },
          "reps_json": {
            "type": "string",
            "sourceNodeId": "{{normalize}}",
            "sourcePath": "$.reps_json"
          }
        },
        "outputSchema": {
          "assigned_owner_id": {
            "type": "string",
            "description": "Selected HubSpot owner ID or an empty string"
          },
          "assigned_owner_email": {
            "type": "string",
            "description": "Email of the selected owner or an empty string"
          },
          "routing_reason": {
            "type": "string",
            "description": "Auditable explanation of the selection result"
          },
          "routing_status": {
            "type": "string",
            "description": "Assigned or held-no-eligible-rep status"
          },
          "eligible_rep_count": {
            "type": "number",
            "description": "Number of reps eligible for this territory and segment"
          },
          "selection_score": {
            "type": "number",
            "description": "Selected rep's open-lead load divided by capacity weight"
          }
        },
        "incomingEdges": [
          {
            "sourceNode": "{{owner_guard}}",
            "isDefaultRoute": true
          }
        ]
      }
    },
    {
      "key": "assignment_result",
      "spec": {
        "nodeType": "conditional",
        "name": "Was an eligible rep found?",
        "inputSchema": {
          "routing_status": {
            "type": "string",
            "sourceNodeId": "{{select_rep}}",
            "sourcePath": "$.routing_status"
          }
        },
        "conditionalMode": "rules",
        "rulesConditionalConfig": {
          "rules": [
            {
              "id": "rep_assigned",
              "name": "Rep assigned",
              "condition": {
                "type": "GroupOp",
                "combinationMode": "And",
                "items": [
                  {
                    "type": "BinOp",
                    "dataPath": [
                      "routing_status"
                    ],
                    "operator": "Equal",
                    "value": "assigned"
                  }
                ]
              }
            }
          ]
        },
        "incomingEdges": [
          {
            "sourceNode": "{{select_rep}}"
          }
        ]
      }
    },
    {
      "key": "prepare_writeback",
      "spec": {
        "nodeType": "code",
        "name": "Prepare HubSpot owner writeback",
        "code": "def handler(context):\n    return {\"hubspot_record_id\": context.get_input(\"hubspot_record_id\") or \"\", \"hubspot_owner_id\": context.get_input(\"assigned_owner_id\") or \"\", \"assigned_owner_email\": context.get_input(\"assigned_owner_email\") or \"\", \"routing_status\": \"assigned\", \"routing_reason\": context.get_input(\"routing_reason\") or \"\"}",
        "inputSchema": {
          "hubspot_record_id": {
            "type": "string",
            "sourceNodeId": "{{normalize}}",
            "sourcePath": "$.hubspot_record_id"
          },
          "assigned_owner_id": {
            "type": "string",
            "sourceNodeId": "{{select_rep}}",
            "sourcePath": "$.assigned_owner_id"
          },
          "assigned_owner_email": {
            "type": "string",
            "sourceNodeId": "{{select_rep}}",
            "sourcePath": "$.assigned_owner_email"
          },
          "routing_reason": {
            "type": "string",
            "sourceNodeId": "{{select_rep}}",
            "sourcePath": "$.routing_reason"
          }
        },
        "outputSchema": {
          "hubspot_record_id": {
            "type": "string",
            "description": "HubSpot record to update"
          },
          "hubspot_owner_id": {
            "type": "string",
            "description": "Owner ID ready for the HubSpot owner field"
          },
          "assigned_owner_email": {
            "type": "string",
            "description": "Selected owner email for review"
          },
          "routing_status": {
            "type": "string",
            "description": "Successful assignment status"
          },
          "routing_reason": {
            "type": "string",
            "description": "Auditable routing explanation"
          }
        },
        "incomingEdges": [
          {
            "sourceNode": "{{assignment_result}}",
            "ruleId": "rep_assigned"
          }
        ]
      }
    },
    {
      "key": "hold_no_rep",
      "spec": {
        "nodeType": "code",
        "name": "Hold lead for RevOps review",
        "code": "def handler(context):\n    return {\"hubspot_record_id\": context.get_input(\"hubspot_record_id\") or \"\", \"routing_status\": \"held_no_eligible_rep\", \"routing_reason\": context.get_input(\"routing_reason\") or \"No eligible rep was found.\", \"eligible_rep_count\": context.get_input(\"eligible_rep_count\") or 0}",
        "inputSchema": {
          "hubspot_record_id": {
            "type": "string",
            "sourceNodeId": "{{normalize}}",
            "sourcePath": "$.hubspot_record_id"
          },
          "routing_reason": {
            "type": "string",
            "sourceNodeId": "{{select_rep}}",
            "sourcePath": "$.routing_reason"
          },
          "eligible_rep_count": {
            "type": "number",
            "sourceNodeId": "{{select_rep}}",
            "sourcePath": "$.eligible_rep_count"
          }
        },
        "outputSchema": {
          "hubspot_record_id": {
            "type": "string",
            "description": "HubSpot record held for review"
          },
          "routing_status": {
            "type": "string",
            "description": "Held-no-eligible-rep terminal status"
          },
          "routing_reason": {
            "type": "string",
            "description": "Explanation of why no assignment was made"
          },
          "eligible_rep_count": {
            "type": "number",
            "description": "Number of reps eligible for the lead"
          }
        },
        "incomingEdges": [
          {
            "sourceNode": "{{assignment_result}}",
            "isDefaultRoute": true
          }
        ]
      }
    }
  ],
  "tests": [
    {
      "name": "Existing owner is preserved",
      "inputs": {
        "hubspot_record_id": "102",
        "email": "owned@example.com",
        "company_domain": "owned.example",
        "existing_owner_id": "owner_existing",
        "country": "US",
        "employee_count": 2500,
        "target_account": true,
        "reps": []
      },
      "expected_terminal": {
        "routing_status": "held_existing_owner",
        "assigned_owner_id": "owner_existing",
        "hubspot_record_id": "102"
      }
    },
    {
      "name": "UKI enterprise lead selects lowest adjusted load",
      "inputs": {
        "hubspot_record_id": "101",
        "email": " Buyer@Example.COM ",
        "company_domain": " Example.COM ",
        "existing_owner_id": "",
        "country": "gb",
        "employee_count": 1200,
        "target_account": false,
        "reps": [
          {
            "hubspot_owner_id": "owner_busy",
            "email": "busy@example.com",
            "active": true,
            "out_of_office": false,
            "regions": [
              "UKI"
            ],
            "segments": [
              "Enterprise"
            ],
            "current_open_leads": 30,
            "capacity_weight": 1
          },
          {
            "hubspot_owner_id": "owner_selected",
            "email": "selected@example.com",
            "active": true,
            "out_of_office": false,
            "regions": [
              "UKI"
            ],
            "segments": [
              "Enterprise"
            ],
            "current_open_leads": 10,
            "capacity_weight": 2
          },
          {
            "hubspot_owner_id": "owner_ooo",
            "email": "ooo@example.com",
            "active": true,
            "out_of_office": true,
            "regions": [
              "UKI"
            ],
            "segments": [
              "Enterprise"
            ],
            "current_open_leads": 0,
            "capacity_weight": 10
          }
        ]
      },
      "expected_terminal": {
        "routing_status": "assigned",
        "hubspot_owner_id": "owner_selected",
        "assigned_owner_email": "selected@example.com",
        "hubspot_record_id": "101"
      }
    },
    {
      "name": "No eligible rep is held for review",
      "inputs": {
        "hubspot_record_id": "103",
        "email": "held@example.com",
        "company_domain": "held.example",
        "existing_owner_id": "",
        "country": "DE",
        "employee_count": 80,
        "target_account": false,
        "reps": [
          {
            "hubspot_owner_id": "owner_dach_enterprise",
            "email": "dach-enterprise@example.com",
            "active": true,
            "out_of_office": false,
            "regions": [
              "DACH"
            ],
            "segments": [
              "Enterprise"
            ],
            "current_open_leads": 3,
            "capacity_weight": 1
          },
          {
            "hubspot_owner_id": "owner_dach_smb_ooo",
            "email": "dach-smb-ooo@example.com",
            "active": true,
            "out_of_office": true,
            "regions": [
              "DACH"
            ],
            "segments": [
              "SMB"
            ],
            "current_open_leads": 0,
            "capacity_weight": 1
          }
        ]
      },
      "expected_terminal": {
        "routing_status": "held_no_eligible_rep",
        "eligible_rep_count": 0,
        "hubspot_record_id": "103"
      }
    }
  ],
  "diagram": "flowchart TD\n    trigger([Manual]) --> normalize[Normalize lead and derive routing keys]\n    normalize --> owner_guard{Does HubSpot already have an owner?}\n    owner_guard -->|yes| hold_existing[Hold lead with existing owner]\n    owner_guard -->|no| select_rep[Select eligible rep by capacity]\n    select_rep --> assignment_result{Was an eligible rep found?}\n    assignment_result -->|yes| prepare_writeback[Prepare HubSpot owner writeback]\n    assignment_result -->|no| hold_review[Hold lead for RevOps review]"
}
