The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Greenhouse Job Ingestion",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 6
}
]
}
},
"id": "schedule-greenhouse",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
-400,
0
]
},
{
"parameters": {
"jsCode": "// Greenhouse public job board API \u2014 no auth required.\n// API: GET https://boards-api.greenhouse.io/v1/boards/{slug}/jobs?content=true\n// Add company slugs here. Find slugs at: https://boards.greenhouse.io/{slug}\nconst companies = [\n 'monzo',\n 'wise',\n 'starling-bank',\n 'cleo',\n 'revolut',\n 'curve',\n 'pismo',\n 'checkout-com',\n 'duolingo',\n 'intercom',\n 'notion',\n 'loom',\n 'plaid',\n 'brex',\n 'vercel',\n 'supabase',\n 'posthog',\n 'linear',\n];\nreturn companies.map(slug => ({ json: { slug } }));"
},
"id": "companies-greenhouse",
"name": "Companies",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-176,
0
]
},
{
"parameters": {
"url": "=https://boards-api.greenhouse.io/v1/boards/{{ $json.slug }}/jobs",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "content",
"value": "true"
}
]
},
"options": {}
},
"id": "fetch-greenhouse",
"name": "Fetch Jobs",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
48,
0
],
"continueOnFail": true,
"onError": "continueRegularOutput"
},
{
"parameters": {
"jsCode": "function stripHtml(html) {\n return (html || '').replace(/<[^>]*>/g, ' ').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/ /g, ' ').replace(/'/g, \"'\").replace(/"/g, '\"').replace(/\\s+/g, ' ').trim();\n}\nconst jobs = $json.jobs || [];\nconst companyName = ($json.company || {}).name || '';\nreturn jobs.map(j => {\n const loc = (j.location || {}).name || '';\n const isRemote = loc.toLowerCase().includes('remote') || (j.content || '').toLowerCase().includes('remote');\n return {\n json: {\n source: 'greenhouse',\n external_id: String(j.id ?? ''),\n company: companyName,\n title: (j.title || '').trim(),\n location: loc,\n remote: isRemote ? 'remote' : 'unknown',\n url: j.absolute_url || '',\n description: stripHtml(j.content || '').slice(0, 8000),\n posted_at: j.updated_at || null,\n }\n };\n});"
},
"id": "normalize-greenhouse",
"name": "Normalize",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
272,
0
]
},
{
"parameters": {
"jsCode": "function simpleHash(str) {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) - hash) + str.charCodeAt(i);\n hash |= 0;\n }\n return Math.abs(hash).toString(16).padStart(8, '0');\n}\nreturn items.map(({ json }) => {\n const base = [json.source, json.external_id, json.company, json.title, json.url].join('|');\n return { json: { ...json, content_hash: simpleHash(base) } };\n});"
},
"id": "hash-greenhouse",
"name": "Hash",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
496,
0
]
},
{
"parameters": {
"method": "POST",
"url": "https://matchpilot-production-a08d.up.railway.app/api/ingest",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "source",
"value": "={{ $json.source }}"
},
{
"name": "external_id",
"value": "={{ $json.external_id }}"
},
{
"name": "company",
"value": "={{ $json.company }}"
},
{
"name": "title",
"value": "={{ $json.title }}"
},
{
"name": "location",
"value": "={{ $json.location }}"
},
{
"name": "remote",
"value": "={{ $json.remote }}"
},
{
"name": "url",
"value": "={{ $json.url }}"
},
{
"name": "description",
"value": "={{ $json.description }}"
},
{
"name": "posted_at",
"value": "={{ $json.posted_at }}"
},
{
"name": "content_hash",
"value": "={{ $json.content_hash }}"
}
]
},
"options": {
"timeout": 15000
}
},
"id": "ingest-greenhouse",
"name": "Ingest",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
720,
0
],
"continueOnFail": true,
"onError": "continueRegularOutput"
},
{
"parameters": {
"jsCode": "return Array.from({length: 100}, (_, i) => ({ json: { i } }));"
},
"id": "loop-greenhouse",
"name": "Loop 100",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
944,
0
]
},
{
"parameters": {
"method": "POST",
"url": "https://matchpilot-production-a08d.up.railway.app/api/worker/score",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "x-worker-secret",
"value": "3eb2bf26e739c83044d5b6c7ea851c4e4c7e6f58afd401f267fa98f78445e6bf"
}
]
},
"options": {
"timeout": 60000
}
},
"id": "worker-greenhouse",
"name": "Trigger Worker",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1168,
0
],
"continueOnFail": true,
"onError": "continueRegularOutput"
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Companies",
"type": "main",
"index": 0
}
]
]
},
"Companies": {
"main": [
[
{
"node": "Fetch Jobs",
"type": "main",
"index": 0
}
]
]
},
"Fetch Jobs": {
"main": [
[
{
"node": "Normalize",
"type": "main",
"index": 0
}
]
]
},
"Normalize": {
"main": [
[
{
"node": "Hash",
"type": "main",
"index": 0
}
]
]
},
"Hash": {
"main": [
[
{
"node": "Ingest",
"type": "main",
"index": 0
}
]
]
},
"Ingest": {
"main": [
[
{
"node": "Loop 100",
"type": "main",
"index": 0
}
]
]
},
"Loop 100": {
"main": [
[
{
"node": "Trigger Worker",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Greenhouse Job Ingestion. Uses httpRequest. Scheduled trigger; 8 nodes.
Source: https://github.com/OskarsZvingulis/MatchPilot/blob/b94053498fa3f8fe4a8479b24d74a099cb9dfe73/n8n-workflows/greenhouse.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.
This template runs two scheduled workflows to govern Microsoft Entra ID (Azure AD) guest accounts by detecting stale users via Microsoft Graph, staging deletions in SharePoint with a 72-hour window, n
Jira-Allure-Auto-Qa. Uses httpRequest, jira. Scheduled trigger; 68 nodes.
Spotify-Sync-Surrealdb-V1. Uses httpRequest, n8n-nodes-surrealdb, spotify. Scheduled trigger; 62 nodes.
As n8n instances scale, teams often lose track of sub-workflows—who uses them, where they are referenced, and whether they can be safely updated. This leads to inefficiencies like unnecessary copies o