{
  "name": "Check visa sponsorship for companies in Google Sheets with Apify",
  "nodes": [
    {
      "parameters": {},
      "id": "967fbfba-ef79-5309-a8f8-61a58a1412ed",
      "name": "Run manually",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        -100
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "days",
              "daysInterval": 1,
              "triggerAtHour": 9
            }
          ]
        }
      },
      "id": "d60b42b6-a922-57bf-840b-57ab204dedd0",
      "name": "Every day at 09:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        100
      ]
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "REPLACE_WITH_YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Companies",
          "mode": "name"
        },
        "options": {}
      },
      "id": "374e7d34-c396-5d7b-a4fb-40e5ce4fb4b1",
      "name": "Read the Companies sheet",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        240,
        0
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "REPLACE_WITH_YOUR_GOOGLE_SHEETS_CREDENTIAL",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Send only companies that have not been checked yet (empty checkedAt), so re-runs cost nothing.\nconst companies = [...new Set(\n  $input.all()\n    .map((i) => i.json)\n    .filter((r) => r.company && !r.checkedAt)\n    .map((r) => String(r.company).trim())\n    .filter(Boolean),\n)].slice(0, 500);\nif (companies.length === 0) return [];\nreturn [{ json: { companies } }];"
      },
      "id": "121449bf-71fd-53df-afca-18088e2ee3b1",
      "name": "Pick unchecked companies",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        0
      ]
    },
    {
      "parameters": {
        "resource": "Actors",
        "operation": "Run actor and get dataset",
        "actorId": {
          "__rl": true,
          "value": "sCgz7xESEPV04PLkp",
          "mode": "id"
        },
        "customBody": "={{ JSON.stringify({ mode: 'employers', companies: $json.companies, includeUk: true, minMatchScore: 0.8, maxJobTitles: 5, maxResults: 0 }) }}",
        "maxTotalChargeUsd": 2
      },
      "id": "8920b67d-6d8f-5c32-97e7-eb893ce323c2",
      "name": "Look up sponsorship records",
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 2,
      "position": [
        720,
        0
      ],
      "credentials": {
        "apifyApi": {
          "id": "REPLACE_WITH_YOUR_APIFY_CREDENTIAL",
          "name": "Apify account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// One row per company you asked about, matched on the `company` column.\n// Companies with no filings and no UK licence get a row too, so they are not re-checked every day.\nconst asked = $('Pick unchecked companies').first().json.companies;\nconst found = new Map();\nfor (const r of $input.all().map((i) => i.json)) {\n  if (r.type === 'employer' && r.input && !found.has(r.input)) found.set(r.input, r);\n}\nconst today = new Date().toISOString().slice(0, 10);\nreturn asked.map((company) => {\n  const r = found.get(company);\n  if (!r) return { json: { company, legalName: '', sponsorsUS: 'no record found', sponsorsUK: 'no record found', checkedAt: today } };\n  const us = (r.h1bCertifiedTotal ?? 0) + (r.permCertifiedTotal ?? 0) > 0;\n  return { json: {\n    company,\n    legalName: r.employerName ?? '',\n    matchScore: r.matchScore ?? '',\n    sponsorsUS: us ? 'yes' : 'no filings found',\n    h1bCertifiedTotal: r.h1bCertifiedTotal ?? 0,\n    h1bCertifiedLatestFY: r.h1bCertifiedLatestFY ?? 0,\n    permCertifiedTotal: r.permCertifiedTotal ?? 0,\n    topJobTitle: r.topJobTitle ?? '',\n    topJobTitleMedianWage: r.topJobTitleMedianWage ?? '',\n    sponsorsUK: r.ukLicensed === true ? 'yes' : r.ukLicensed === false ? 'not on register' : 'not checked',\n    ukRating: r.ukBestRating ?? '',\n    ukRoutes: Array.isArray(r.ukRoutes) ? r.ukRoutes.join(', ') : '',\n    checkedAt: today,\n  } };\n});"
      },
      "id": "9da26d6e-764a-5880-b1e6-02bdf720d7da",
      "name": "Shape the results",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        960,
        0
      ]
    },
    {
      "parameters": {
        "operation": "appendOrUpdate",
        "documentId": {
          "__rl": true,
          "value": "REPLACE_WITH_YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Companies",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {},
          "matchingColumns": [
            "company"
          ],
          "schema": []
        },
        "options": {}
      },
      "id": "82a44a65-faf8-5ac7-9987-2c7388c16c77",
      "name": "Write results to the sheet",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1200,
        0
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "REPLACE_WITH_YOUR_GOOGLE_SHEETS_CREDENTIAL",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "content": "## Read the sheet\nOnly rows without `checkedAt` are sent.",
        "height": 460,
        "width": 680,
        "color": 7
      },
      "id": "b92bd09a-2760-5ac2-9b01-a4da325cbb54",
      "name": "Section 1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -50,
        -230
      ]
    },
    {
      "parameters": {
        "content": "## Look up and write back\nOne row per company, matched on `company`.",
        "height": 260,
        "width": 680,
        "color": 7
      },
      "id": "c93a09c8-a7af-5dfd-9456-88b8c0130c3b",
      "name": "Section 2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        670,
        -130
      ]
    },
    {
      "parameters": {
        "content": "## Check visa sponsorship for companies in Google Sheets\n\nFor international job seekers, recruiters and relocation advisers who keep a list of employers and want to know which ones sponsor visas.\n\n### How it works\n1. Start it by hand or let the daily schedule run. It reads the **Companies** tab and keeps rows whose `checkedAt` is empty.\n2. The **visa-sponsors** Actor looks each name up in US Department of Labor H-1B and PERM disclosure data and in the UK register of licensed sponsors.\n3. A Code node writes one row back per company: matched legal name, H-1B and PERM counts, the most common sponsored job title and its median wage, and the UK licence rating and routes. Companies with no record are marked too, so they aren't checked again.\n\n### Setup\n1. Add your own Apify API token as an *Apify API* credential.\n2. Make a Google Sheet with a tab named **Companies** and the header row `company`, `checkedAt`. Fill `company` with names (`Google`) or domains (`microsoft.com`).\n3. Paste the sheet ID into both Sheets nodes and pick your Google credential.\n\n### Requirements\nApify account (free plan: up to 50 companies per run) and Google Sheets. The Actor charges $2.50 per 1,000 records; the node caps each run at $2.\n\n**Community node:** uses the verified Apify node (`@apify/n8n-nodes-apify`). On n8n Cloud it installs from the canvas; on self-hosted n8n install it under Settings > Community nodes.\n\n### Customization tips\nSet `minMatchScore` to 1 for exact legal names only, or `includeUk` to false for US data only. Clear a `checkedAt` cell to check that company again.\n\nMade by locaihost, a small studio that builds its tools with AI agents.",
        "height": 880,
        "width": 560
      },
      "id": "b823c5a6-c535-532f-a284-1a2e048b0caa",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -670,
        -230
      ]
    }
  ],
  "connections": {
    "Run manually": {
      "main": [
        [
          {
            "node": "Read the Companies sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every day at 09:00": {
      "main": [
        [
          {
            "node": "Read the Companies sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read the Companies sheet": {
      "main": [
        [
          {
            "node": "Pick unchecked companies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pick unchecked companies": {
      "main": [
        [
          {
            "node": "Look up sponsorship records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Look up sponsorship records": {
      "main": [
        [
          {
            "node": "Shape the results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Shape the results": {
      "main": [
        [
          {
            "node": "Write results to the sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}
