{
  "name": "Save LinkedIn job postings to Google Sheets with Apify",
  "nodes": [
    {
      "parameters": {
        "content": "## Save LinkedIn job postings to Google Sheets\n\n**Who's it for**\nRecruiters, job seekers and analysts who want a sheet of the LinkedIn job postings for a role and location, refreshed every day.\n\n**How it works**\n1. The schedule starts the workflow every morning.\n2. The Set node holds the job title or keywords, the location, the postings to fetch per run and your Google Sheet.\n3. The Apify node runs the [LinkedIn Jobs Scraper](https://apify.com/logical_scrapers/linkedin-jobs-scraper?utm_source=n8n&utm_medium=template&utm_campaign=save-linkedin-job-postings) Actor, which reads public LinkedIn job search results. No LinkedIn account or cookies are needed.\n4. The job ID, title, company, location, employment type, seniority, industry, posting and expiry dates and the job URL are kept.\n5. Google Sheets adds new postings as rows and updates the ones it has seen before, matched on `linkedinJobId`.\n\n**How to set up**\n1. Install the Apify community node (`@apify/n8n-nodes-apify`) and connect your Apify account in the Apify node.\n2. Connect your Google account in the Google Sheets node.\n3. Create a sheet with this header row:\n`linkedinJobId, title, company, location, employmentType, seniorityLevel, industry, postedAt, validThrough, jobUrl`\n4. Open **Set search and sheet** and enter your keywords, location and the sheet URL.\n\n**Requirements**\nAn Apify account (the Actor is pay per result, see its Store page for the price) and a Google account.\n\nSetup guide: https://www.logicalscrapers.com/integrations/n8n#save-linkedin-job-postings",
        "height": 680,
        "width": 560
      },
      "id": "0e882aa2-4127-45e9-aa99-b6785d71d055",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -680,
        -260
      ]
    },
    {
      "parameters": {
        "content": "### 1. Your settings\nEdit **Set search and sheet**: job title or keywords, location, postings to fetch per run, spend limit per run and the Google Sheet to write to.",
        "height": 420,
        "width": 440,
        "color": 7
      },
      "id": "7b250e06-4b69-444c-a930-bed844c57782",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -60,
        -260
      ]
    },
    {
      "parameters": {
        "content": "### 2. Search LinkedIn jobs\nRuns the LinkedIn Jobs Scraper Actor on your Apify account and waits for the postings. `maxItems` is the number of postings fetched per run, and what a run costs depends on it.",
        "height": 420,
        "width": 260,
        "color": 7
      },
      "id": "1275620c-505d-45be-adc8-811210337266",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        420,
        -260
      ]
    },
    {
      "parameters": {
        "content": "### 3. Save to the sheet\nKeeps the columns the sheet needs, then appends new postings and updates known ones, matched on `linkedinJobId`. Add or remove fields in **Keep sheet columns** to change the columns.",
        "height": 420,
        "width": 480,
        "color": 7
      },
      "id": "d74e9a2e-e994-47f7-a42d-967704195d3e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        720,
        -260
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 8
            }
          ]
        }
      },
      "id": "46b09f93-28f3-4de6-af93-68672b519354",
      "name": "Run every morning",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "22f5f0d3-d528-4e16-aa79-5f7049c286e4",
              "name": "keywords",
              "value": "product manager",
              "type": "string"
            },
            {
              "id": "4c06b49c-ec84-4fec-a618-d747858cbd2c",
              "name": "location",
              "value": "United States",
              "type": "string"
            },
            {
              "id": "1b513b75-59c1-4745-a005-a68fee2a1bc5",
              "name": "maxItems",
              "value": 25,
              "type": "number"
            },
            {
              "id": "c1274c9c-bd7c-4d0a-ad6e-579536467198",
              "name": "maxCostPerRunUsd",
              "value": 0.25,
              "type": "number"
            },
            {
              "id": "444e80e7-6feb-4e4a-ae17-d8c9f1eab835",
              "name": "googleSheetUrl",
              "value": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit",
              "type": "string"
            },
            {
              "id": "d13f9a0d-4180-425e-a8fb-8f1193289f42",
              "name": "sheetName",
              "value": "Sheet1",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "47c4140d-dbd6-4e20-ae6a-6bcc071c5bfc",
      "name": "Set search and sheet",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        0
      ]
    },
    {
      "parameters": {
        "resource": "Actors",
        "operation": "Run actor and get dataset",
        "actorId": "logical_scrapers~linkedin-jobs-scraper",
        "customBody": "={\n  \"keywords\": {{ JSON.stringify($json.keywords) }},\n  \"location\": {{ JSON.stringify($json.location) }},\n  \"maxItems\": {{ $json.maxItems }}\n}",
        "memory": 512,
        "maxTotalChargeUsd": "={{ $('Set search and sheet').first().json.maxCostPerRunUsd }}"
      },
      "id": "325d8b55-520e-4836-a691-f93a8ba5167c",
      "name": "Search LinkedIn jobs",
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        500,
        0
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "90420a30-f916-4f42-a45f-b916c3818180",
              "name": "linkedinJobId",
              "value": "={{ $json.linkedinJobId }}",
              "type": "string"
            },
            {
              "id": "fbe397fb-0fc4-4263-aea8-b97c17fa77ed",
              "name": "title",
              "value": "={{ $json.title }}",
              "type": "string"
            },
            {
              "id": "4972bd07-bd6f-44d2-a036-7efc87b80c4d",
              "name": "company",
              "value": "={{ $json.company }}",
              "type": "string"
            },
            {
              "id": "f102b4e8-15f6-4464-adcc-a8570b525924",
              "name": "location",
              "value": "={{ $json.location }}",
              "type": "string"
            },
            {
              "id": "9f2e859f-819f-4646-a055-899fb08f8858",
              "name": "employmentType",
              "value": "={{ $json.employmentType }}",
              "type": "string"
            },
            {
              "id": "bd3411f7-443f-4f9b-a798-3e0cc4d37cb5",
              "name": "seniorityLevel",
              "value": "={{ $json.seniorityLevel }}",
              "type": "string"
            },
            {
              "id": "1eab82b7-847c-44e0-aebb-465721e6d574",
              "name": "industry",
              "value": "={{ $json.industry }}",
              "type": "string"
            },
            {
              "id": "6f87efd6-3769-4042-ae13-3400bfd7d896",
              "name": "postedAt",
              "value": "={{ $json.postedAt }}",
              "type": "string"
            },
            {
              "id": "77bd7c16-af51-4f23-aaa0-e7658a3764d5",
              "name": "validThrough",
              "value": "={{ $json.validThrough }}",
              "type": "string"
            },
            {
              "id": "492ab154-c963-4b39-a19f-8440b0042455",
              "name": "jobUrl",
              "value": "={{ $json.jobUrl }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "3f846bfb-3bc3-4199-a2ae-650308132c73",
      "name": "Keep sheet columns",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        800,
        0
      ]
    },
    {
      "parameters": {
        "operation": "appendOrUpdate",
        "documentId": {
          "__rl": true,
          "value": "={{ $('Set search and sheet').first().json.googleSheetUrl }}",
          "mode": "url"
        },
        "sheetName": {
          "__rl": true,
          "value": "={{ $('Set search and sheet').first().json.sheetName }}",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {},
          "matchingColumns": [
            "linkedinJobId"
          ],
          "schema": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "id": "ba30ba69-0ee8-46ce-a1a5-14168119a0c0",
      "name": "Save jobs to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1020,
        0
      ]
    }
  ],
  "connections": {
    "Run every morning": {
      "main": [
        [
          {
            "node": "Set search and sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set search and sheet": {
      "main": [
        [
          {
            "node": "Search LinkedIn jobs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search LinkedIn jobs": {
      "main": [
        [
          {
            "node": "Keep sheet columns",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Keep sheet columns": {
      "main": [
        [
          {
            "node": "Save jobs to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}
