{
  "name": "Automate company enrichment in Google Sheets with Bounce Watch",
  "nodes": [
    {
      "parameters": {
        "width": 520,
        "height": 980,
        "content": "## Automate company enrichment in Google Sheets with Bounce Watch\n\nBounce Watch tells you what a company is and what just happened there - headcount, founding year, location, and dated events such as funding rounds and senior hires. What the API covers: bouncewatch.com/products/data-enrichment-api\n\nA spreadsheet of company domains is where most target lists start, and a domain is usually all it holds. This workflow fills in the rest of the row on a schedule, without anyone opening a tab.\n\n### How it works\n\nEvery morning the workflow reads your sheet and keeps only the rows that carry a domain and have not been filled in yet. Each remaining domain goes to Bounce Watch, which returns the company profile, and the last node writes headcount, founding year, country, city, description and the LinkedIn page back onto the same row, matched on the domain. Fields we do not hold come back empty and the cell is left as it is.\n\n### Setup\n\n1. Get an API key at bouncewatch.com/register/api. It is free, no card, and every new account starts with 2,500 credits. Paste it into the Bounce Watch credential.\n2. Connect your Google account on both Google Sheets nodes, then pick the spreadsheet and the tab.\n3. Your sheet needs a Domain column. Add Employees, Founded, Country, City, Description and LinkedIn columns for the answers, or remove the ones you do not want from the last node.\n\nA profile lookup spends credits, so the filter is doing real work: a row that is already filled is never paid for twice.\n\n### Customization tips\n\nSwap the schedule for a webhook to enrich a row the moment it is added."
      },
      "id": "bwSticky Note",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -380,
        -120
      ]
    },
    {
      "parameters": {
        "width": 680,
        "height": 300,
        "content": "## Only the rows that need it\n\nRows without a domain cannot be looked up, and rows already carrying a headcount do not need to be. Both are dropped before anything is spent.",
        "color": 7
      },
      "id": "bwSection 1",
      "name": "Section 1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        150,
        -170
      ]
    },
    {
      "parameters": {
        "width": 440,
        "height": 300,
        "content": "## Back onto the same row\n\nMatched on the domain column, so each answer lands on the row it came from. Fields we do not hold are left alone rather than blanked.",
        "color": 7
      },
      "id": "bwSection 2",
      "name": "Section 2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        870,
        -170
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 7
            }
          ]
        }
      },
      "id": "bw0101-0000-4000-8000-000000000101",
      "name": "Every morning",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [
        220,
        0
      ],
      "notes": "Once a day is enough. Firmographics do not move hourly."
    },
    {
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        }
      },
      "id": "bw0102-0000-4000-8000-000000000102",
      "name": "Read the company list",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        460,
        0
      ],
      "notes": "Pick the spreadsheet and tab. The sheet needs a Domain column."
    },
    {
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bw0103-0000-4000-8000-000000000103",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ !!$json.Domain && !$json.Employees }}",
              "rightValue": ""
            }
          ]
        }
      },
      "id": "bw0104-0000-4000-8000-000000000104",
      "name": "Rows not filled in yet",
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.2,
      "position": [
        700,
        0
      ],
      "notes": "A filled row is never looked up, so the same row is never paid for twice."
    },
    {
      "parameters": {
        "resource": "company",
        "operation": "get",
        "domain": "={{ $json.Domain.toString().trim().toLowerCase().replace(/^https?:\\/\\//, \"\").replace(/^www\\./, \"\").split(\"/\")[0] }}"
      },
      "id": "bw0105-0000-4000-8000-000000000105",
      "name": "Get the company profile",
      "type": "n8n-nodes-bouncewatch.bounceWatch",
      "typeVersion": 1,
      "position": [
        940,
        0
      ],
      "credentials": {
        "bounceWatchApi": {
          "name": "<your credential>"
        }
      },
      "notes": "Base profile only. Fields we do not hold come back empty."
    },
    {
      "parameters": {
        "columns": {
          "value": {
            "Domain": "={{ $('Rows not filled in yet').item.json.Domain }}",
            "Employees": "={{ $json.company.employee_count || undefined }}",
            "Founded": "={{ $json.company.founded_year || undefined }}",
            "Country": "={{ $json.company.headquarter_country || undefined }}",
            "City": "={{ $json.company.headquarter_city || undefined }}",
            "Description": "={{ $json.company.description || undefined }}",
            "LinkedIn": "={{ $json.company.linkedin_url || undefined }}"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Domain"
          ]
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        }
      },
      "id": "bw0106-0000-4000-8000-000000000106",
      "name": "Write the firmographics back",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1180,
        0
      ],
      "notes": "Matched on Domain, so the answer lands on the row it came from."
    }
  ],
  "connections": {
    "Every morning": {
      "main": [
        [
          {
            "node": "Read the company list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read the company list": {
      "main": [
        [
          {
            "node": "Rows not filled in yet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rows not filled in yet": {
      "main": [
        [
          {
            "node": "Get the company profile",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get the company profile": {
      "main": [
        [
          {
            "node": "Write the firmographics back",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}