{
  "id": "SpeedToLeadMain0",
  "name": "Speed to Lead",
  "nodes": [
    {
      "id": "3614d322-3ba6-4fa6-8549-d4d38c7cacf6",
      "parameters": {
        "httpMethod": "POST",
        "path": "lead",
        "options": {}
      },
      "name": "Form submitted",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        0,
        300
      ],
      "webhookId": "a7c9e1d2-5f3b-4c8a-9e1d-2b5f3c8a9e1d"
    },
    {
      "id": "3991dff5-1c15-4f4e-9d9f-c89b09d19c28",
      "parameters": {
        "jsCode": "// Take whatever the form sent and make one clean lead item.\nconst b = $json.body || $json;\nconst clean = (v) => (v == null ? '' : String(v).trim());\nconst lead = {\n  name: clean(b.name),\n  email: clean(b.email),\n  phone: clean(b.phone),\n  message: clean(b.message),\n  source: clean(b.source) || 'website-form',\n  received: clean(b.received) || new Date().toISOString(),\n  company: \"Ridgeline Heating & Plumbing\",\n  companyPhone: \"(208) 555-0142\",\n};\nlead.systemPrompt = \"You read new customer messages for Ridgeline Heating & Plumbing, a heating, cooling and plumbing company, and you return one JSON object. Nothing else. No markdown, no code fences, no text before or after the JSON.\\n\\nReturn exactly these keys:\\n\\n- \\\"name\\\": the customer's first name if you can tell it. Use the form name first, then the message. If neither gives a name, use \\\"there\\\".\\n- \\\"service\\\": what they need, in two to five words. Examples: \\\"furnace repair\\\", \\\"AC quote\\\", \\\"basement water leak\\\", \\\"sink leak\\\". If the message is not a real request, use \\\"unclear\\\".\\n- \\\"urgency\\\": one of \\\"high\\\", \\\"normal\\\", \\\"low\\\".\\n- \\\"budget\\\": a dollar figure or range if they gave one, as a short string like \\\"$6,000\\\" or \\\"$5k-$8k\\\". Otherwise null.\\n- \\\"summary\\\": one plain sentence the owner can read in two seconds. Lead with the problem. Include the timing they asked for if they gave one.\\n- \\\"reply\\\": the email we send back to the customer. Follow the reply rules below.\\n\\nUrgency rules:\\n\\n- \\\"high\\\" when there is a risk to safety or of damage right now. That includes: no heat or no AC in bad weather, active water or a leak still running, a gas smell, sewage backup, sparking or burning smells, a baby, a child, an elderly person or someone with a medical need in the home, or words like \\\"tonight\\\", \\\"right now\\\", \\\"emergency\\\", \\\"asap\\\", \\\"still coming in\\\". If any of these appear, urgency is \\\"high\\\". When in doubt between high and normal, choose high.\\n- \\\"low\\\" only when they say there is no rush AND give no timeframe and no budget: \\\"no rush\\\", \\\"just getting estimates\\\", \\\"someday\\\", \\\"whenever\\\", \\\"down the road\\\", \\\"just curious\\\".\\n- \\\"normal\\\" for everything else. A season, a month, a rough date, or a budget makes it \\\"normal\\\" even if they also say \\\"sometime\\\" or \\\"no hurry\\\", someone with a timeframe or a budget is planning to buy.\\n- A message that is not a real request, like \\\"asdf test\\\", is \\\"normal\\\" with service \\\"unclear\\\".\\n\\nReply rules:\\n\\n- Write to the customer by first name. If you do not know it, open with \\\"Hi there,\\\".\\n- Two to four short sentences. Plain words. No exclamation points. No emojis.\\n- Show you read it: name their actual problem in their own words.\\n- For \\\"high\\\": say we are on it and they will hear from a real person very soon, and that if it is an emergency they can call or text (208) 555-0142 right now.\\n- For \\\"normal\\\" and \\\"low\\\": say a real person will reach out to set up a time, and that they can call or text (208) 555-0142 if that is easier.\\n- For \\\"unclear\\\": ask, in one friendly line, what they need help with, and give the phone number.\\n- Never promise an arrival time, a price, or that a technician is already on the way.\\n- Never mention that an AI wrote this. The workflow adds its own honest note below the reply.\\n- Sign off with a line break, then \\\"Ridgeline Heating & Plumbing\\\".\\n\\nIf the message is empty, garbled, or you cannot tell what they need, still return valid JSON with \\\"service\\\" \\\"unclear\\\", \\\"urgency\\\" \\\"normal\\\", \\\"budget\\\" null, a \\\"summary\\\" that says the message needs a human look, and the \\\"unclear\\\" reply.\";\nlead.userPrompt =\n  'Form name: ' + (lead.name || '(blank)') + '\\n' +\n  'Form email: ' + (lead.email || '(blank)') + '\\n' +\n  'Form phone: ' + (lead.phone || '(blank)') + '\\n\\n' +\n  'Message:\\n' + (lead.message || '(blank)');\nreturn [{ json: lead }];"
      },
      "name": "Shape the lead",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        220,
        300
      ]
    },
    {
      "id": "7e2a0521-d866-4cee-8a06-a498e43d041a",
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "id",
          "value": "claude-haiku-4-5-20251001"
        },
        "messages": {
          "values": [
            {
              "role": "user",
              "content": "={{ $json.userPrompt }}"
            }
          ]
        },
        "simplify": true,
        "options": {
          "system": "={{ $json.systemPrompt }}",
          "maxTokens": 600,
          "temperature": 0
        }
      },
      "name": "Read the lead",
      "type": "@n8n/n8n-nodes-langchain.anthropic",
      "typeVersion": 1,
      "position": [
        440,
        300
      ],
      "credentials": {
        "anthropicApi": {
          "id": "SpeedToLeadAnthr",
          "name": "Speed to Lead - Anthropic"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "id": "64ba7331-2d24-4042-b5f9-64d267edd1a2",
      "parameters": {
        "jsCode": "// Turn Claude's answer into the record we keep. If Claude failed or returned junk,\n// fall back to a safe reply and urgency \"normal\" instead of dying.\nconst lead = $('Shape the lead').first().json;\nconst raw = $json;\nlet text = '';\nif (!raw.error && Array.isArray(raw.content)) {\n  text = (raw.content.find((c) => c.type === 'text') || {}).text || '';\n}\nlet data = null;\nlet fallback = '';\nif (raw.error) {\n  fallback = 'AI call failed: ' + (raw.error.message || JSON.stringify(raw.error));\n} else {\n  try {\n    data = JSON.parse(text.replace(/^\\s*```(?:json)?\\s*/i, '').replace(/\\s*```\\s*$/, '').trim());\n  } catch (e) {\n    fallback = 'AI returned unreadable JSON';\n  }\n}\nconst levels = ['high', 'normal', 'low'];\nconst firstName = (lead.name || '').split(/\\s+/)[0] || (data && data.name) || 'there';\nconst genericReply =\n  'Hi ' + firstName + ',\\n\\n' +\n  'We got your message and a real person will reach out shortly to help. ' +\n  'If it is an emergency, call or text ' + lead.companyPhone + ' right now.\\n\\n' +\n  lead.company;\nconst note = '\\n\\n--\\nThis reply went out automatically so you would hear back fast. A real person is next.';\nreturn [{\n  json: {\n    Name: lead.name || (data && data.name && data.name !== 'there' ? data.name : '') || 'Unknown',\n    Email: lead.email,\n    Phone: lead.phone,\n    Message: lead.message,\n    Service: (data && data.service) || 'unclear',\n    Urgency: data && levels.includes(data.urgency) ? data.urgency : 'normal',\n    Budget: (data && data.budget) || '',\n    Summary: (data && data.summary) || ('Needs a human read. ' + (fallback ? '(' + fallback + ') ' : '') + 'They wrote: ' + lead.message),\n    Reply: ((data && data.reply) || genericReply) + note,\n    Status: 'new',\n    Received: lead.received,\n    firstName,\n    aiFallback: fallback,\n  },\n}];"
      },
      "name": "Parse and validate",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        660,
        300
      ]
    },
    {
      "id": "a4d210b3-96ca-4a05-8cc7-1e4c01c3a4ad",
      "parameters": {
        "jsCode": "// Only the columns the Leads table has. Blank optional fields are left out so Airtable\n// never sees an empty email or phone.\nconst j = $json;\nconst rec = { Name: j.Name, Message: j.Message, Service: j.Service, Urgency: j.Urgency,\n  Summary: j.Summary, Reply: j.Reply, Status: j.Status, Received: j.Received };\nif (j.Email) rec.Email = j.Email;\nif (j.Phone) rec.Phone = j.Phone;\nif (j.Budget) rec.Budget = j.Budget;\nreturn [{ json: rec }];"
      },
      "name": "Pick CRM fields",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        300
      ]
    },
    {
      "id": "a54c3d41-afa2-4c43-8038-04d2e17d5df7",
      "parameters": {
        "resource": "record",
        "operation": "create",
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "__AIRTABLE_BASE_ID__"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "__AIRTABLE_TABLE_ID__"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {},
          "matchingColumns": [],
          "schema": []
        },
        "options": {
          "typecast": true
        }
      },
      "name": "Log the lead",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.2,
      "position": [
        1100,
        300
      ],
      "credentials": {
        "airtableTokenApi": {
          "id": "SpeedToLeadAirtb",
          "name": "Speed to Lead - Airtable"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "id": "3853e419-002b-44a0-8925-1d17e5d496d6",
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "29420f48-c588-4775-81c0-4d879c3c81ad",
              "leftValue": "={{ $('Parse and validate').first().json.Email }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Has an email?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        1320,
        300
      ]
    },
    {
      "id": "440bb7d0-4bd0-40a5-97a6-e1a1ff501d31",
      "parameters": {
        "fromEmail": "Ridgeline Heating & Plumbing <__SENDER_EMAIL__>",
        "toEmail": "={{ $('Parse and validate').first().json.Email }}",
        "subject": "=We got your message, {{ $('Parse and validate').first().json.firstName }}",
        "emailFormat": "text",
        "text": "={{ $('Parse and validate').first().json.Reply }}",
        "options": {
          "appendAttribution": false
        }
      },
      "name": "Reply to the lead",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        1540,
        200
      ],
      "credentials": {
        "smtp": {
          "id": "SpeedToLeadSmtp0",
          "name": "Speed to Lead - Gmail SMTP"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "id": "e85442d2-8cf3-4103-85af-d436e23f8774",
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "57e426da-250d-452a-b9a3-c8823e480d7a",
                    "leftValue": "={{ $('Parse and validate').first().json.Urgency }}",
                    "rightValue": "high",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "high"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "0779dc40-f2f9-4e09-83cf-f70c0f68ac7a",
                    "leftValue": "={{ $('Parse and validate').first().json.Urgency }}",
                    "rightValue": "normal",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "normal"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "823a5d2f-82b0-4444-be9d-36b5d87258bd",
                    "leftValue": "={{ $('Parse and validate').first().json.Urgency }}",
                    "rightValue": "low",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "low"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "name": "How urgent?",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        1760,
        300
      ]
    },
    {
      "id": "4aa540bc-d561-4555-a2df-8c5d44f6fae0",
      "parameters": {
        "chatId": "__TELEGRAM_CHAT_ID__",
        "text": "=🔴 URGENT LEAD\n{{ $('Parse and validate').first().json.Name }}: {{ $('Parse and validate').first().json.Summary }}\n📞 {{ $('Parse and validate').first().json.Phone  || 'no phone' }}\n✉️ {{ $('Parse and validate').first().json.Email  || 'no email' }}\nBudget: {{ $('Parse and validate').first().json.Budget  || 'not given' }}{{ $('Parse and validate').first().json.aiFallback ? '\\n\\n⚠️ The AI read failed (' + $('Parse and validate').first().json.aiFallback + '). A generic reply went out. Read the message yourself.' : '' }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "name": "Alert the owner now",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1980,
        180
      ],
      "credentials": {
        "telegramApi": {
          "id": "SpeedToLeadTeleg",
          "name": "Speed to Lead - Telegram"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "id": "9312368c-c363-484a-bb84-e19e330851b0",
      "parameters": {
        "chatId": "__TELEGRAM_CHAT_ID__",
        "text": "=New lead · {{ $('Parse and validate').first().json.Urgency }}\n{{ $('Parse and validate').first().json.Name }}: {{ $('Parse and validate').first().json.Summary }}\n📞 {{ $('Parse and validate').first().json.Phone  || 'no phone' }} · Budget: {{ $('Parse and validate').first().json.Budget  || 'not given' }}{{ $('Parse and validate').first().json.aiFallback ? '\\n\\n⚠️ The AI read failed (' + $('Parse and validate').first().json.aiFallback + '). Read the message yourself.' : '' }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "name": "Quiet note to the owner",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1980,
        420
      ],
      "credentials": {
        "telegramApi": {
          "id": "SpeedToLeadTeleg",
          "name": "Speed to Lead - Telegram"
        }
      }
    },
    {
      "id": "ff997bff-7dab-4d3c-9a27-7e2a66bdf62a",
      "parameters": {
        "amount": 2,
        "unit": "minutes"
      },
      "name": "Wait for a reply",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        2200,
        300
      ],
      "webhookId": "b8d0f2e3-6a4c-4d9b-8f2e-3c6a4d9b8f2e"
    },
    {
      "id": "08ce8648-d41a-4251-95eb-b3c3dcc0b21d",
      "parameters": {
        "resource": "record",
        "operation": "get",
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "__AIRTABLE_BASE_ID__"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "__AIRTABLE_TABLE_ID__"
        },
        "id": "={{ $('Log the lead').first().json.id }}",
        "options": {}
      },
      "name": "Check the record",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.2,
      "position": [
        2420,
        300
      ],
      "credentials": {
        "airtableTokenApi": {
          "id": "SpeedToLeadAirtb",
          "name": "Speed to Lead - Airtable"
        }
      }
    },
    {
      "id": "63accd91-47ea-40ad-bc53-5eda28061ab5",
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "a8316b62-7bc8-40e9-8441-57c7fcac1430",
              "leftValue": "={{ $json.Status || ($json.fields && $json.fields.Status) }}",
              "rightValue": "new",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Still waiting?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        2640,
        300
      ]
    },
    {
      "id": "817d1df4-7d46-426c-b6fb-fcd2bbb95c8b",
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "373e584b-ddc9-40ce-89d6-0bd044f160a2",
              "leftValue": "={{ $('Parse and validate').first().json.Email }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Has an email? (follow-up)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        2860,
        200
      ]
    },
    {
      "id": "767c9ffa-49ea-4069-b1d7-75fce236ed03",
      "parameters": {
        "fromEmail": "Ridgeline Heating & Plumbing <__SENDER_EMAIL__>",
        "toEmail": "={{ $('Parse and validate').first().json.Email }}",
        "subject": "=Still need help, {{ $('Parse and validate').first().json.firstName }}?",
        "emailFormat": "text",
        "text": "=Hi {{ $('Parse and validate').first().json.firstName }},\n\nJust checking you got our note about your {{ $('Parse and validate').first().json.Service }}. If you still want a hand with it, reply here and we will set up a time, or call or text (208) 555-0142.\n\nRidgeline Heating & Plumbing",
        "options": {
          "appendAttribution": false
        }
      },
      "name": "Send the follow-up",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        3080,
        100
      ],
      "credentials": {
        "smtp": {
          "id": "SpeedToLeadSmtp0",
          "name": "Speed to Lead - Gmail SMTP"
        }
      }
    },
    {
      "id": "20a8439a-c7ac-4d10-bdd6-9cde31ddcfc6",
      "parameters": {
        "chatId": "__TELEGRAM_CHAT_ID__",
        "text": "=⏰ No reply yet, and no email on file\n{{ $('Parse and validate').first().json.Name }}: {{ $('Parse and validate').first().json.Summary }}\n📞 {{ $('Parse and validate').first().json.Phone  || 'no phone' }}\nGive them a call.",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "name": "Nudge the owner",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        3080,
        300
      ],
      "credentials": {
        "telegramApi": {
          "id": "SpeedToLeadTeleg",
          "name": "Speed to Lead - Telegram"
        }
      }
    },
    {
      "id": "55f94c28-5397-4b9c-b183-e4ae76b57504",
      "parameters": {
        "jsCode": "// The record id from the create step, plus the new status. Airtable matches on id.\nreturn [{ json: { id: $('Log the lead').first().json.id, Status: 'followed-up' } }];"
      },
      "name": "Mark followed-up",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3300,
        200
      ]
    },
    {
      "id": "d2164b46-3050-43a3-90ec-79637d363236",
      "parameters": {
        "resource": "record",
        "operation": "update",
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "__AIRTABLE_BASE_ID__"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "__AIRTABLE_TABLE_ID__"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {},
          "matchingColumns": [
            "id"
          ],
          "schema": []
        },
        "options": {
          "typecast": true
        }
      },
      "name": "Update the record",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.2,
      "position": [
        3520,
        200
      ],
      "credentials": {
        "airtableTokenApi": {
          "id": "SpeedToLeadAirtb",
          "name": "Speed to Lead - Airtable"
        }
      }
    },
    {
      "id": "72b823cc-56eb-4a17-bd7b-425479414a46",
      "parameters": {},
      "name": "They replied. Done.",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        2860,
        440
      ]
    },
    {
      "id": "594947dd-b172-49d5-b721-0d477976f630",
      "parameters": {
        "jsCode": "// Something external failed. Fail the run on purpose, with the lead written into the\n// error message, so the error workflow can hand the owner the lead and not just a stack trace.\nconst e = ($json && $json.error) || {};\nconst lead = $('Shape the lead').first().json;\nconst what = e.message || e.description || JSON.stringify(e);\nthrow new Error(\n  $prevNode.name + ' failed: ' + what +\n  ' || LEAD: ' + (lead.name || 'no name') + ' · ' + (lead.phone || 'no phone') + ' · ' +\n  (lead.email || 'no email') + ' · \"' + lead.message + '\"'\n);"
      },
      "name": "Fail loudly, lead attached",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1540,
        620
      ]
    },
    {
      "id": "853b526f-a171-47a3-bfc0-4dd11be18fb3",
      "parameters": {
        "content": "## Speed to Lead\nForm → Claude reads it → CRM → reply to the lead → owner alert → wait → follow-up if still quiet.\n\nAnything external that breaks routes to **Fail loudly, lead attached**, which fails the run with the lead written into the error. The error workflow turns that into a Telegram alert, so a broken pipeline still hands the owner the lead.\n\nWait is 2 minutes for the demo. Production: 2 days.",
        "height": 220,
        "width": 520
      },
      "name": "About",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    }
  ],
  "connections": {
    "Form submitted": {
      "main": [
        [
          {
            "node": "Shape the lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Shape the lead": {
      "main": [
        [
          {
            "node": "Read the lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read the lead": {
      "main": [
        [
          {
            "node": "Parse and validate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse and validate": {
      "main": [
        [
          {
            "node": "Pick CRM fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pick CRM fields": {
      "main": [
        [
          {
            "node": "Log the lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log the lead": {
      "main": [
        [
          {
            "node": "Has an email?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fail loudly, lead attached",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has an email?": {
      "main": [
        [
          {
            "node": "Reply to the lead",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "How urgent?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reply to the lead": {
      "main": [
        [
          {
            "node": "How urgent?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fail loudly, lead attached",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "How urgent?": {
      "main": [
        [
          {
            "node": "Alert the owner now",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Quiet note to the owner",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Quiet note to the owner",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Quiet note to the owner",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Alert the owner now": {
      "main": [
        [
          {
            "node": "Wait for a reply",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fail loudly, lead attached",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Quiet note to the owner": {
      "main": [
        [
          {
            "node": "Wait for a reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for a reply": {
      "main": [
        [
          {
            "node": "Check the record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check the record": {
      "main": [
        [
          {
            "node": "Still waiting?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Still waiting?": {
      "main": [
        [
          {
            "node": "Has an email? (follow-up)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "They replied. Done.",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has an email? (follow-up)": {
      "main": [
        [
          {
            "node": "Send the follow-up",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Nudge the owner",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send the follow-up": {
      "main": [
        [
          {
            "node": "Mark followed-up",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Nudge the owner": {
      "main": [
        [
          {
            "node": "Mark followed-up",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark followed-up": {
      "main": [
        [
          {
            "node": "Update the record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "errorWorkflow": "SpeedToLeadError",
    "timezone": "America/Denver",
    "saveManualExecutions": true
  },
  "active": false
}
