This workflow corresponds to n8n.io template #10888 — we link there as the canonical source.
This workflow follows the Agent → Documentdefaultdataloader recipe pattern — see all workflows that pair these two integrations.
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 →
{
"id": "Pw1XfgxO4K0AUG1K",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "F1 Race Winner Prediction Using Real-Time and Historical Data",
"tags": [],
"nodes": [
{
"id": "ac0d98a1-34d1-4da5-9f18-e128775b754d",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1456,
784
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 8
}
]
}
},
"typeVersion": 1.2
},
{
"id": "326f30b7-ebb4-482a-af1d-6f54c22ade95",
"name": "Workflow Configuration",
"type": "n8n-nodes-base.set",
"position": [
-1296,
784
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "f1ApiBaseUrl",
"type": "string",
"value": "https://ergast.com/api/f1"
},
{
"id": "id-2",
"name": "currentSeason",
"type": "string",
"value": "2025"
},
{
"id": "id-3",
"name": "newsApiUrl",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__News API endpoint for F1 updates__>"
},
{
"id": "id-4",
"name": "weatherApiUrl",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Weather API endpoint__>"
},
{
"id": "id-5",
"name": "historicalYears",
"type": "number",
"value": 3
},
{
"id": "id-6",
"name": "confidenceThreshold",
"type": "number",
"value": 0.75
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "a3ae51ae-5f82-4d1c-a7be-b99cbcab0cbb",
"name": "Fetch Current F1 Season Data",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1056,
496
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.f1ApiBaseUrl }}/{{ $('Workflow Configuration').first().json.currentSeason }}.json",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"typeVersion": 4.3
},
{
"id": "f2314633-09a3-4713-81a5-2b03870e15df",
"name": "Fetch Driver Standings",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1056,
688
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.f1ApiBaseUrl }}/{{ $('Workflow Configuration').first().json.currentSeason }}/driverStandings.json",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"typeVersion": 4.3
},
{
"id": "85d690ca-12ae-4f7a-88f7-af8861365781",
"name": "Fetch Constructor Standings",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1056,
1008
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.f1ApiBaseUrl }}/{{ $('Workflow Configuration').first().json.currentSeason }}/constructorStandings.json",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"typeVersion": 4.3
},
{
"id": "7c486d1f-838c-40e7-8d19-df4acf11131a",
"name": "Merge F1 Data",
"type": "n8n-nodes-base.code",
"position": [
-832,
592
],
"parameters": {
"jsCode": "// Merge F1 data from multiple sources\nconst items = $input.all();\n\nlet seasonData = null;\nlet driverStandings = null;\nlet constructorStandings = null;\n\n// Process each input item and categorize by source\nfor (const item of items) {\n const data = item.json;\n \n // Identify the type of data based on structure\n if (data.MRData && data.MRData.RaceTable) {\n // This is season/race data\n seasonData = data.MRData.RaceTable;\n } else if (data.MRData && data.MRData.StandingsTable && data.MRData.StandingsTable.StandingsLists) {\n const standingsList = data.MRData.StandingsTable.StandingsLists[0];\n \n if (standingsList.DriverStandings) {\n // This is driver standings\n driverStandings = standingsList.DriverStandings;\n } else if (standingsList.ConstructorStandings) {\n // This is constructor standings\n constructorStandings = standingsList.ConstructorStandings;\n }\n }\n}\n\n// Create merged data object\nconst mergedData = {\n season: seasonData,\n driverStandings: driverStandings,\n constructorStandings: constructorStandings,\n timestamp: new Date().toISOString()\n};\n\n// Return as single item\nreturn [{ json: mergedData }];"
},
"typeVersion": 2
},
{
"id": "a628c315-cce2-4847-a617-7893235b987d",
"name": "F1 Prediction Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-384,
480
],
"parameters": {
"text": "You are an expert F1 race analyst with deep knowledge of Formula 1 racing. You have access to comprehensive tools: 1) Historical F1 Data Search - query past race results, qualifying, circuits, and driver metrics, 2) Real-time F1 news, 3) Weather forecasts, 4) Statistical analysis capabilities. Analyze the provided current season data (driver standings, constructor standings, race schedule) and use ALL available tools to gather additional context. Predict the winner of the next F1 race with: Winner name, Confidence level (0-1), Top 3 predicted finishers, Key factors (minimum 5), Risk factors, Weather impact assessment. Be data-driven and cite specific statistics from historical data.",
"options": {},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "5e28f4ef-69a7-4cd4-ab56-8d55f4f1fc65",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-528,
816
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "gpt-4o"
},
"options": {
"temperature": 0.3
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "052bee4d-cedc-4bd7-ba0c-749fd6d5f8e8",
"name": "Real-Time F1 News Tool",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
-432,
704
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.newsApiUrl }}",
"options": {},
"toolDescription": "Fetches the latest Formula 1 news, team updates, driver injuries, and race developments"
},
"typeVersion": 4.3
},
{
"id": "0ba84859-71cd-49fc-9b70-f91ef01f3304",
"name": "Weather Data Tool",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
-304,
704
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.weatherApiUrl }}",
"options": {},
"toolDescription": "Fetches weather forecast for the upcoming F1 race location including temperature, precipitation, and wind conditions"
},
"typeVersion": 4.3
},
{
"id": "e2b834d2-3b27-4f5a-83c1-0b62f00a9780",
"name": "Format Prediction Output",
"type": "n8n-nodes-base.set",
"position": [
320,
512
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "predictionDate",
"type": "string",
"value": "={{ $now.toISO() }}"
},
{
"id": "id-2",
"name": "predictionSource",
"type": "string",
"value": "AI Agent Analysis"
},
{
"id": "id-3",
"name": "dataVersion",
"type": "string",
"value": "v1.0"
},
{
"id": "id-4",
"name": "confidenceScore",
"type": "string",
"value": "={{ $('F1 Prediction Agent').item.json.output }}"
},
{
"id": "id-5",
"name": "predictedWinner",
"type": "string",
"value": "={{ $('F1 Prediction Agent').item.json.output }}"
},
{
"id": "id-6",
"name": "analysisDepth",
"type": "string",
"value": "comprehensive"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "e7d272dc-8cb0-4272-a543-8edf00fa6b59",
"name": "Fetch Historical Race Results",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1056,
848
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.f1ApiBaseUrl }}/{{ Number($('Workflow Configuration').first().json.currentSeason) - 1 }}/results.json",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"typeVersion": 4.3
},
{
"id": "30113435-ebf2-4280-a9c2-13d045950fbc",
"name": "Fetch Qualifying Results",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1056,
1200
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.f1ApiBaseUrl }}/{{ $('Workflow Configuration').first().json.currentSeason }}/qualifying.json",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"typeVersion": 4.3
},
{
"id": "338ec321-f8c6-4627-9bfd-3dfa0d05a309",
"name": "Fetch Circuit Information",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1056,
1392
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.f1ApiBaseUrl }}/{{ $('Workflow Configuration').first().json.currentSeason }}/circuits.json",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"typeVersion": 4.3
},
{
"id": "c066baf6-02ee-4ed2-a609-e221fc607352",
"name": "Historical Data Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreInMemory",
"position": [
336,
1152
],
"parameters": {
"mode": "insert",
"memoryKey": {
"__rl": true,
"mode": "id",
"value": "f1_historical_data"
}
},
"typeVersion": 1.3
},
{
"id": "cc23bbd6-913a-4e31-91e6-296a6067d506",
"name": "OpenAI Embeddings",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
-192,
848
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "b4e75689-fda5-4c51-9fa6-ac1589aca12d",
"name": "Document Loader",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
544,
1296
],
"parameters": {
"options": {},
"textSplittingMode": "custom"
},
"typeVersion": 1.1
},
{
"id": "f97fb1dc-a132-4117-b7fd-727f6c10ea64",
"name": "Recursive Text Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
"position": [
544,
1408
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "aa9f47f4-5791-40ad-9548-35f371d683ac",
"name": "Historical Data Retrieval Tool",
"type": "@n8n/n8n-nodes-langchain.vectorStoreInMemory",
"position": [
-176,
704
],
"parameters": {
"mode": "retrieve-as-tool",
"topK": 10,
"memoryKey": {
"__rl": true,
"mode": "id",
"value": "f1_historical_data"
},
"toolDescription": "Search through historical F1 race results, qualifying data, circuit information, and driver performance metrics from past seasons"
},
"typeVersion": 1.3
},
{
"id": "51ae0cae-2af1-47a4-9fd1-1d5c6a199bf2",
"name": "Calculate Driver Performance Metrics",
"type": "n8n-nodes-base.code",
"position": [
-512,
1120
],
"parameters": {
"jsCode": "// Calculate advanced driver performance metrics\nconst items = $input.all();\n\n// Extract driver data from aggregated historical data\nconst driverMetrics = [];\n\n// Process each item to calculate metrics\nfor (const item of items) {\n const data = item.json;\n \n // Initialize metrics object for each driver\n const drivers = {};\n \n // Extract race results and calculate metrics\n if (data.races && Array.isArray(data.races)) {\n for (const race of data.races) {\n if (race.Results && Array.isArray(race.Results)) {\n for (const result of race.Results) {\n const driverId = result.Driver?.driverId || 'unknown';\n \n if (!drivers[driverId]) {\n drivers[driverId] = {\n driverId: driverId,\n driverName: `${result.Driver?.givenName || ''} ${result.Driver?.familyName || ''}`.trim(),\n races: [],\n totalPoints: 0,\n podiums: 0,\n wins: 0,\n dnfs: 0,\n qualifyingPositions: [],\n finishingPositions: []\n };\n }\n \n // Add race data\n const position = parseInt(result.position) || 999;\n const points = parseFloat(result.points) || 0;\n const status = result.status || '';\n \n drivers[driverId].races.push({\n raceName: race.raceName,\n position: position,\n points: points,\n status: status,\n grid: parseInt(result.grid) || 0\n });\n \n drivers[driverId].totalPoints += points;\n drivers[driverId].finishingPositions.push(position);\n \n if (result.grid) {\n drivers[driverId].qualifyingPositions.push(parseInt(result.grid));\n }\n \n // Count podiums and wins\n if (position === 1) drivers[driverId].wins++;\n if (position <= 3) drivers[driverId].podiums++;\n \n // Count DNFs (Did Not Finish)\n if (status && !status.includes('Finished') && !status.includes('Lapped')) {\n drivers[driverId].dnfs++;\n }\n }\n }\n }\n }\n \n // Calculate advanced metrics for each driver\n for (const driverId in drivers) {\n const driver = drivers[driverId];\n const totalRaces = driver.races.length;\n \n if (totalRaces > 0) {\n // Average finishing position\n const avgFinishPosition = driver.finishingPositions.reduce((a, b) => a + b, 0) / driver.finishingPositions.length;\n \n // Podium rate\n const podiumRate = (driver.podiums / totalRaces) * 100;\n \n // DNF rate\n const dnfRate = (driver.dnfs / totalRaces) * 100;\n \n // Points per race\n const pointsPerRace = driver.totalPoints / totalRaces;\n \n // Average qualifying position\n const avgQualifyingPosition = driver.qualifyingPositions.length > 0\n ? driver.qualifyingPositions.reduce((a, b) => a + b, 0) / driver.qualifyingPositions.length\n : null;\n \n // Consistency score (lower standard deviation = more consistent)\n const mean = avgFinishPosition;\n const variance = driver.finishingPositions.reduce((sum, pos) => sum + Math.pow(pos - mean, 2), 0) / driver.finishingPositions.length;\n const consistencyScore = 100 - Math.min(Math.sqrt(variance) * 5, 100); // Scale to 0-100\n \n // Win rate\n const winRate = (driver.wins / totalRaces) * 100;\n \n // Recent form (last 5 races average position)\n const recentRaces = driver.finishingPositions.slice(-5);\n const recentForm = recentRaces.reduce((a, b) => a + b, 0) / recentRaces.length;\n \n driverMetrics.push({\n driverId: driver.driverId,\n driverName: driver.driverName,\n totalRaces: totalRaces,\n totalPoints: driver.totalPoints,\n wins: driver.wins,\n podiums: driver.podiums,\n dnfs: driver.dnfs,\n metrics: {\n averageFinishingPosition: parseFloat(avgFinishPosition.toFixed(2)),\n podiumRate: parseFloat(podiumRate.toFixed(2)),\n winRate: parseFloat(winRate.toFixed(2)),\n dnfRate: parseFloat(dnfRate.toFixed(2)),\n pointsPerRace: parseFloat(pointsPerRace.toFixed(2)),\n averageQualifyingPosition: avgQualifyingPosition ? parseFloat(avgQualifyingPosition.toFixed(2)) : null,\n consistencyScore: parseFloat(consistencyScore.toFixed(2)),\n recentFormAverage: parseFloat(recentForm.toFixed(2))\n },\n raceHistory: driver.races\n });\n }\n }\n}\n\n// Sort by total points descending\ndriverMetrics.sort((a, b) => b.totalPoints - a.totalPoints);\n\n// Return enriched data with calculated metrics\nreturn driverMetrics.map(driver => ({ json: driver }));"
},
"typeVersion": 2
},
{
"id": "619b5d04-e9fd-446b-bdae-03ef2a936947",
"name": "Check Prediction Confidence",
"type": "n8n-nodes-base.if",
"position": [
624,
512
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "id-1",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $('Format Prediction Output').item.json.confidenceScore }}",
"rightValue": "={{ $('Workflow Configuration').first().json.confidenceThreshold }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "11b7c328-fbce-4c81-8323-64e267a5fa80",
"name": "Store Prediction in Database",
"type": "n8n-nodes-base.postgres",
"position": [
848,
416
],
"parameters": {
"table": {
"__rl": true,
"mode": "name",
"value": "<__PLACEHOLDER_VALUE__Database table name for predictions__>"
},
"schema": {
"__rl": true,
"mode": "list",
"value": "public"
},
"columns": {
"value": {
"data_version": "={{ $json.dataVersion }}",
"full_analysis": "={{ $json.full_analysis }}",
"prediction_date": "={{ $json.predictionDate }}",
"confidence_score": "={{ $json.confidence_score }}",
"predicted_winner": "={{ $json.predicted_winner }}",
"prediction_source": "={{ $json.predictionSource }}"
},
"mappingMode": "defineBelow"
},
"options": {}
},
"typeVersion": 2.6
},
{
"id": "58ade5fc-bb26-43f7-b9a7-d494f09eed34",
"name": "Send High Confidence Alert",
"type": "n8n-nodes-base.slack",
"position": [
848,
608
],
"parameters": {
"text": "=\ud83c\udfc1 **High Confidence F1 Race Prediction Alert** \ud83c\udfc1\n\n**Predicted Winner:** {{ $json.predictedWinner }}\n**Confidence Score:** {{ $json.confidenceScore }}%\n\n**Key Factors:**\n{{ $json.keyFactors }}\n\n**Analysis Timestamp:** {{ $json.predictionDate }}\n\nThis prediction is based on comprehensive analysis of driver standings, constructor performance, historical data, current news, and weather conditions.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "<__PLACEHOLDER_VALUE__Slack channel ID for high confidence predictions__>"
},
"otherOptions": {
"includeLinkToWorkflow": true
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "f5101f59-88c2-467e-ae81-20dd29e11284",
"name": "Log to Prediction Tracker",
"type": "n8n-nodes-base.googleSheets",
"position": [
848,
800
],
"parameters": {
"columns": {
"value": {
"Date": "={{ $json.predictionDate }}",
"Data Version": "={{ $json.dataVersion }}",
"Analysis Source": "={{ $json.predictionSource }}",
"Confidence Score": "={{ $json.confidenceScore }}",
"Predicted Winner": "={{ $json.predictedWinner }}"
},
"schema": [
{
"id": "Date",
"required": false,
"displayName": "Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Predicted Winner",
"required": false,
"displayName": "Predicted Winner",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "Confidence Score",
"required": false,
"displayName": "Confidence Score",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "Analysis Source",
"required": false,
"displayName": "Analysis Source",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "Data Version",
"required": false,
"displayName": "Data Version",
"defaultMatch": false,
"canBeUsedToMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Date"
]
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "<__PLACEHOLDER_VALUE__Sheet name for predictions log__>"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "<__PLACEHOLDER_VALUE__Google Sheets document ID__>"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "5f44490c-ced5-4c88-a800-4e6e791c5d15",
"name": "Aggregate Historical Data",
"type": "n8n-nodes-base.aggregate",
"position": [
-848,
976
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "b493d9bd-d55a-403c-b6aa-9b6f1adfa613",
"name": "Statistical Analysis Tool",
"type": "@n8n/n8n-nodes-langchain.toolCode",
"position": [
112,
640
],
"parameters": {
"jsCode": "// Statistical Analysis Tool for F1 Data\n// Performs calculations including mean, median, standard deviation, win rates, and correlation analysis\n\nconst data = JSON.parse(query);\n\n// Helper function to calculate mean\nfunction mean(values) {\n if (!values || values.length === 0) return 0;\n return values.reduce((sum, val) => sum + val, 0) / values.length;\n}\n\n// Helper function to calculate median\nfunction median(values) {\n if (!values || values.length === 0) return 0;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];\n}\n\n// Helper function to calculate standard deviation\nfunction standardDeviation(values) {\n if (!values || values.length === 0) return 0;\n const avg = mean(values);\n const squareDiffs = values.map(value => Math.pow(value - avg, 2));\n return Math.sqrt(mean(squareDiffs));\n}\n\n// Helper function to calculate win rate\nfunction winRate(wins, total) {\n if (!total || total === 0) return 0;\n return (wins / total) * 100;\n}\n\n// Helper function to calculate correlation coefficient\nfunction correlation(x, y) {\n if (!x || !y || x.length !== y.length || x.length === 0) return 0;\n const n = x.length;\n const meanX = mean(x);\n const meanY = mean(y);\n \n let numerator = 0;\n let denomX = 0;\n let denomY = 0;\n \n for (let i = 0; i < n; i++) {\n const diffX = x[i] - meanX;\n const diffY = y[i] - meanY;\n numerator += diffX * diffY;\n denomX += diffX * diffX;\n denomY += diffY * diffY;\n }\n \n if (denomX === 0 || denomY === 0) return 0;\n return numerator / Math.sqrt(denomX * denomY);\n}\n\n// Perform analysis based on data structure\nconst results = {\n timestamp: new Date().toISOString(),\n analysis: {}\n};\n\n// Analyze driver performance if available\nif (data.driverPoints && Array.isArray(data.driverPoints)) {\n results.analysis.driverStats = {\n mean: mean(data.driverPoints),\n median: median(data.driverPoints),\n stdDev: standardDeviation(data.driverPoints)\n };\n}\n\n// Calculate win rates if available\nif (data.wins !== undefined && data.totalRaces !== undefined) {\n results.analysis.winRate = winRate(data.wins, data.totalRaces).toFixed(2) + '%';\n}\n\n// Calculate correlation if two datasets provided\nif (data.dataset1 && data.dataset2 && Array.isArray(data.dataset1) && Array.isArray(data.dataset2)) {\n results.analysis.correlation = correlation(data.dataset1, data.dataset2).toFixed(4);\n}\n\n// Return formatted results\nreturn JSON.stringify(results, null, 2);",
"description": "Perform statistical analysis on F1 data including win probability calculations, trend analysis, and performance correlations"
},
"typeVersion": 1.3
},
{
"id": "eca22c3b-2970-4fbf-b99e-95650797f563",
"name": "OpenAI Embeddings1",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
336,
1344
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "23512903-7148-42c2-838b-ae46e90fc9cb",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1472,
-32
],
"parameters": {
"width": 448,
"height": 288,
"content": "## How It Works\nEvery day at 8 AM, the workflow automatically retrieves the latest F1 data\u2014including driver standings, qualifying results, race schedules, and circuit information. All sources are merged into a unified dataset, and driver performance metrics are computed using historical trends. An AI agent, enhanced with vectorized race history, evaluates patterns and generates race-winner predictions. When the confidence score exceeds the defined threshold, the system pushes an automated Slack alert and records the full analysis in the database and Google Sheets."
},
"typeVersion": 1
},
{
"id": "13cbacbe-a977-4acc-affe-97c9afdde95f",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1008,
-32
],
"parameters": {
"width": 624,
"height": 288,
"content": "## Setup Steps\n1. Update the workflow configuration with: `newsApiUrl`, `weatherApiUrl`, `historicalYears`, and `confidenceThreshold`.\n2. Connect PostgreSQL using the schema:\n **prediction_date, predicted_winner, confidence_score, prediction_source, data_version, full_analysis**.\n3. Provide the Slack channel ID for sending high-confidence alerts.\n4. Specify the Google Sheets document ID and sheet name for prediction logging.\n5. Test connectivity to the Ergast API (no authentication required)."
},
"typeVersion": 1
},
{
"id": "567cb0ba-8843-411c-b454-e31814333baa",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-352,
160
],
"parameters": {
"color": 3,
"width": 576,
"height": 112,
"content": "## Use Cases\nApplicable for sports analytics dashboards, betting platforms, F1 news sites, and fantasy F1 leagues. Provides daily race predictions with confidence scores "
},
"typeVersion": 1
},
{
"id": "271b72d8-657d-4908-aeb5-023d99239d0b",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
256,
144
],
"parameters": {
"color": 4,
"width": 400,
"height": 128,
"content": "## Customization\nExtend by adding constructor predictions (modify AI prompt). Integrate Discord or Teams instead of Slack.\n\n"
},
"typeVersion": 1
},
{
"id": "384d4620-82c8-4d56-a663-551035d3ada5",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
144
],
"parameters": {
"color": 6,
"width": 400,
"height": 128,
"content": "\n## Benefits\nSaves time by automating data collection, improves accuracy using multiple performance metrics and historical patterns."
},
"typeVersion": 1
},
{
"id": "091c0237-ef60-4b13-b5f0-402b659c1676",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1472,
304
],
"parameters": {
"color": 7,
"width": 576,
"height": 1216,
"content": "## Data Collection\n\nRetrieves live F1 standings, historical results, qualifying data, and circuit info via the Ergast API.\n\n**Why:** Fresh, multi-source data is vital. Standings show driver momentum, and historical circuits reveal recurring performance patterns."
},
"typeVersion": 1
},
{
"id": "568517f0-ae58-4969-996f-eefb668baf6e",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-880,
304
],
"parameters": {
"color": 7,
"width": 256,
"height": 864,
"content": "## Data Processing\n\nMerges data and calculates 8 driver metrics, including podium rate, consistency, and recent form.\n\n**Why:** Metrics reveal patterns raw data "
},
"typeVersion": 1
},
{
"id": "b864770c-1c47-46b4-8dbf-1ec9fdcb47ac",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-608,
304
],
"parameters": {
"color": 7,
"width": 848,
"height": 656,
"content": "## AI Prediction\n\nA LangChain agent (GPT-4o) analyzes the dataset with historical context, news, and weather, outputting a winner prediction with confidence.\n\n**Why:** AI synthesizes complex data at scale, linking weather, past performance, and team news. \n"
},
"typeVersion": 1
},
{
"id": "e5be296b-8ab8-468e-a099-7cade2d9ee53",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
272,
304
],
"parameters": {
"color": 7,
"width": 816,
"height": 656,
"content": "## Confidence Validation\n\nCompares scores against a 0.75 threshold; high-confidence predictions move to alerts and storage \n\n**Why:** Reduces alert fatigue and ensures only reliable insights are acted upon."
},
"typeVersion": 1
},
{
"id": "d2bc78ca-b6a1-4a26-adab-04adc768b23a",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-608,
976
],
"parameters": {
"color": 7,
"width": 736,
"height": 304,
"content": "## Driver Performance Metrics\nCalculates 8 advanced metrics (podium rate, consistency score, recent form, DNF rate, points per race, average positions). Why: Raw standings don't capture true performance patterns across different circuits and conditions."
},
"typeVersion": 1
},
{
"id": "b93ff098-080b-479d-946b-cf71eb1c7ba6",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
144,
976
],
"parameters": {
"color": 7,
"width": 944,
"height": 560,
"content": "## Historical Data Vectorization Pipeline\nTransforms 3 years of F1 historical data into searchable embeddings via OpenAI. Document Loader ingests raw data, Recursive Text Splitter chunks information into contextual units.\n\nWhy: Enables semantic search so AI can find similar race scenarios from the past\u2014critical for accurate predictions."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "41e3178d-bda2-4381-a84c-d55ee0c0331c",
"connections": {
"Merge F1 Data": {
"main": [
[
{
"node": "F1 Prediction Agent",
"type": "main",
"index": 0
}
]
]
},
"Document Loader": {
"ai_document": [
[
{
"node": "Historical Data Vector Store",
"type": "ai_document",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "F1 Prediction Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"OpenAI Embeddings": {
"ai_embedding": [
[
{
"node": "Historical Data Retrieval Tool",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Weather Data Tool": {
"ai_tool": [
[
{
"node": "F1 Prediction Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"OpenAI Embeddings1": {
"ai_embedding": [
[
{
"node": "Historical Data Vector Store",
"type": "ai_embedding",
"index": 0
}
]
]
},
"F1 Prediction Agent": {
"main": [
[
{
"node": "Format Prediction Output",
"type": "main",
"index": 0
}
]
]
},
"Fetch Driver Standings": {
"main": [
[
{
"node": "Merge F1 Data",
"type": "main",
"index": 0
}
]
]
},
"Real-Time F1 News Tool": {
"ai_tool": [
[
{
"node": "F1 Prediction Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Workflow Configuration": {
"main": [
[
{
"node": "Fetch Current F1 Season Data",
"type": "main",
"index": 0
},
{
"node": "Fetch Driver Standings",
"type": "main",
"index": 0
},
{
"node": "Fetch Constructor Standings",
"type": "main",
"index": 0
},
{
"node": "Fetch Historical Race Results",
"type": "main",
"index": 0
},
{
"node": "Fetch Qualifying Results",
"type": "main",
"index": 0
},
{
"node": "Fetch Circuit Information",
"type": "main",
"index": 0
}
]
]
},
"Recursive Text Splitter": {
"ai_textSplitter": [
[
{
"node": "Document Loader",
"type": "ai_textSplitter",
"index": 0
}
]
]
},
"Fetch Qualifying Results": {
"main": [
[
{
"node": "Aggregate Historical Data",
"type": "main",
"index": 0
}
]
]
},
"Format Prediction Output": {
"main": [
[
{
"node": "Check Prediction Confidence",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Historical Data": {
"main": [
[
{
"node": "Calculate Driver Performance Metrics",
"type": "main",
"index": 0
}
]
]
},
"Fetch Circuit Information": {
"main": [
[
{
"node": "Aggregate Historical Data",
"type": "main",
"index": 0
}
]
]
},
"Statistical Analysis Tool": {
"ai_tool": [
[
{
"node": "F1 Prediction Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Check Prediction Confidence": {
"main": [
[
{
"node": "Send High Confidence Alert",
"type": "main",
"index": 0
},
{
"node": "Store Prediction in Database",
"type": "main",
"index": 0
}
],
[
{
"node": "Log to Prediction Tracker",
"type": "main",
"index": 0
}
]
]
},
"Fetch Constructor Standings": {
"main": [
[
{
"node": "Merge F1 Data",
"type": "main",
"index": 0
}
]
]
},
"Fetch Current F1 Season Data": {
"main": [
[
{
"node": "Merge F1 Data",
"type": "main",
"index": 0
}
]
]
},
"Fetch Historical Race Results": {
"main": [
[
{
"node": "Aggregate Historical Data",
"type": "main",
"index": 0
}
]
]
},
"Historical Data Retrieval Tool": {
"ai_tool": [
[
{
"node": "F1 Prediction Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Calculate Driver Performance Metrics": {
"main": [
[
{
"node": "Historical Data Vector Store",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleSheetsOAuth2ApiopenAiApislackOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Every day at 8 AM, the workflow automatically retrieves the latest F1 data—including driver standings, qualifying results, race schedules, and circuit information. All sources are merged into a unified dataset, and driver performance metrics are computed using historical trends.…
Source: https://n8n.io/workflows/10888/ — 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.
Supercharge your trading decisions with this end-to-end AI automation that connects market intelligence, technical analysis, and automated trade execution — all without manual intervention.
WooriFisa. Uses agent, httpRequest, documentDefaultDataLoader, vectorStorePinecone. Scheduled trigger; 86 nodes.
This workflow automates patient communication for medical clinics using the WhatsApp Business API. It supports appointment booking, rescheduling, service inquiries, follow-ups, and document submission
WooriFisa 최종. Uses memoryMongoDbChat, agent, httpRequest, documentDefaultDataLoader. Scheduled trigger; 68 nodes.
This workflow automates end-to-end customer journey management by intelligently routing queries through multiple AI models (OpenAI, Claude) based on complexity and context. Designed for customer succe