{
  "name": "Screen CVs against job descriptions with Gmail, easybits, Airtable and Slack",
  "nodes": [
    {
      "id": "f2d12e48-2668-4535-acc3-128f3bd7d1c3",
      "name": "Sticky Note — Header",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3344,
        976
      ],
      "parameters": {
        "width": 656,
        "height": 1212,
        "content": "## 📄 CV & Resume Screener\n### Powered by Gmail · easybits.tech · Airtable · Slack\n\nAutomatically reads CVs from Gmail, extracts structured candidate data using AI, scores each applicant against your o"
      }
    },
    {
      "id": "3a1f6b36-74eb-493e-a748-71dc842f2f8f",
      "name": "Sticky Note — Step 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4021,
        1396
      ],
      "parameters": {
        "width": 406,
        "height": 428,
        "content": "### Step 1 · Get Email & Attachment\n\n📧 **Gmail Trigger** polls every minute for unread emails matching:\n`has:attachment subject:(Application OR CV OR Resume OR Bewerbung)`\n\n**Setup required:**\n- Conne"
      }
    },
    {
      "id": "f3118ccb-bfd0-43d4-8388-f7ce02dfa5a0",
      "name": "Sticky Note — Step 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4477,
        1396
      ],
      "parameters": {
        "width": 390,
        "height": 428,
        "content": "### Step 2 · Download & Prepare PDF\n\n📥 Downloads the full email via Gmail API, extracts the PDF attachment, and base64-encodes it.\n\n⚠️ **File size limit:** PDFs over ~600 KB will be rejected by the Co"
      }
    },
    {
      "id": "32fa7ad3-fbc7-4d06-bbd9-5a74fbbdb07e",
      "name": "Sticky Note — Step 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4891,
        1268
      ],
      "parameters": {
        "width": 234,
        "height": 556,
        "content": "### Step 3 · Extract CV with easybits\n\n🤖 Sends the base64 PDF to the easybits.tech AI pipeline and returns structured JSON (name, email, skills, experience, education, etc.)\n\n**Setup required:**\n- Add"
      }
    },
    {
      "id": "6607e358-4b04-4712-aef0-0f3bd26d7f8b",
      "name": "Sticky Note — Step 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5119,
        1220
      ],
      "parameters": {
        "width": 226,
        "height": 604,
        "content": "### Step 4 · Fetch Open Job\n\n📋 Queries Airtable for the first record where `status = \"Open\"` to get the active job's requirements.\n\n**Setup required:**\n- Update the **Airtable Base ID** and **Jobs tab"
      }
    },
    {
      "id": "1f738c86-57e3-4625-8c3c-569f0bafbc15",
      "name": "Sticky Note — Step 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5348,
        1220
      ],
      "parameters": {
        "width": 216,
        "height": 604,
        "content": "### Step 5 · Score CV vs Job\n\n🧮 Compares the candidate's extracted CV text against each item in the job's `tech_stack` field.\n\n**Scoring formula:**\n`score = matched skills ÷ total required skills × 10"
      }
    },
    {
      "id": "172948e1-bb9f-4419-9edd-c764b667fc78",
      "name": "Sticky Note — Step 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5581,
        1220
      ],
      "parameters": {
        "width": 198,
        "height": 604,
        "content": "### Step 6 · Route by Score\n\n🔀 Routes candidates based on their match score:\n\n- ✅ **≥ 60%** → `true` branch → **Shortlisted**\n- 🔎 **< 60%** → `false` branch → **In Review**\n\n**Customise:**\n- Change th"
      }
    },
    {
      "id": "7f530826-8eae-4ed3-8a2a-f559c8629759",
      "name": "Sticky Note — Step 7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5788,
        1188
      ],
      "parameters": {
        "width": 456,
        "height": 732,
        "content": "### Step 7 · Save to Airtable & Notify on Slack\n\n💾 Creates a candidate record in your Airtable **Candidates** table with status set to either `Shortlisted` or `In Review`.\n\n📣 Posts a formatted summary"
      }
    },
    {
      "id": "88dce86a-3ee8-46ec-8e93-62ae9ca6dd26",
      "name": "Gmail: Watch CV Emails",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        4064,
        1664
      ]
    },
    {
      "id": "80d51d67-5511-406a-9f09-35125123c900",
      "name": "Download Email & Attachment",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4288,
        1664
      ]
    },
    {
      "id": "ff0c2db5-ea81-4070-bf93-d82d2a131937",
      "name": "Convert PDF to Base64",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4512,
        1664
      ]
    },
    {
      "id": "b7020e7c-6334-4dd0-a669-6699b5eb65fe",
      "name": "Prepare PDF Payload",
      "type": "n8n-nodes-base.code",
      "position": [
        4736,
        1664
      ]
    },
    {
      "id": "aaf48e8a-6c2f-4a08-9d63-463602e13a30",
      "name": "easybits: Extract CV Data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4960,
        1664
      ]
    },
    {
      "id": "3e929414-7fe0-47f8-bc5c-68cd6b2c11f3",
      "name": "Airtable - Fetch Open Job",
      "type": "n8n-nodes-base.airtable",
      "position": [
        5184,
        1664
      ]
    },
    {
      "id": "3a4f786f-7ad4-4934-b02a-ce28e77a1a92",
      "name": "Score CV vs Job Description ",
      "type": "n8n-nodes-base.code",
      "position": [
        5408,
        1664
      ]
    },
    {
      "id": "0ae553ee-ca8d-44f0-bb71-8a38be3e34f1",
      "name": "Route by Score ",
      "type": "n8n-nodes-base.if",
      "position": [
        5632,
        1664
      ]
    },
    {
      "id": "f9c742df-dd7c-4a27-a223-868a59333725",
      "name": "Airtable: Save Reviewed Candidate",
      "type": "n8n-nodes-base.airtable",
      "position": [
        5856,
        1568
      ]
    },
    {
      "id": "e9ffc87f-0677-44b5-8b55-a4184a1b70b8",
      "name": "Slack: Notify For Review",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        6080,
        1568
      ]
    },
    {
      "id": "e8e35dcf-a86d-479d-84d9-8cbabc8d1801",
      "name": "Slack: Notify For Review1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        6080,
        1760
      ]
    },
    {
      "id": "00384117-dbd3-44df-8db5-aec96644c251",
      "name": "Airtable: Save Review Candidate",
      "type": "n8n-nodes-base.airtable",
      "position": [
        5856,
        1760
      ]
    }
  ],
  "connections": {
    "Route by Score ": {
      "main": [
        [
          {
            "node": "Airtable: Save Reviewed Candidate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Airtable: Save Review Candidate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare PDF Payload": {
      "main": [
        [
          {
            "node": "easybits: Extract CV Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert PDF to Base64": {
      "main": [
        [
          {
            "node": "Prepare PDF Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail: Watch CV Emails": {
      "main": [
        [
          {
            "node": "Download Email & Attachment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Airtable - Fetch Open Job": {
      "main": [
        [
          {
            "node": "Score CV vs Job Description ",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "easybits: Extract CV Data": {
      "main": [
        [
          {
            "node": "Airtable - Fetch Open Job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Email & Attachment": {
      "main": [
        [
          {
            "node": "Convert PDF to Base64",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Score CV vs Job Description ": {
      "main": [
        [
          {
            "node": "Route by Score ",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Airtable: Save Review Candidate": {
      "main": [
        [
          {
            "node": "Slack: Notify For Review1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Airtable: Save Reviewed Candidate": {
      "main": [
        [
          {
            "node": "Slack: Notify For Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}