This workflow corresponds to n8n.io template #12151 — we link there as the canonical source.
This workflow follows the Google Sheets → HTTP Request 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": "ZfwuCVdff9lGumXB",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Automated IBKR Trade Report to Google Sheets Journal",
"tags": [],
"nodes": [
{
"id": "f1ab6f5d-f612-42da-8972-2f5662d1860e",
"name": "1. Request Flex Report",
"type": "n8n-nodes-base.httpRequest",
"notes": "Starts Flex Report generation",
"position": [
656,
688
],
"parameters": {
"url": "https://gdcdyn.interactivebrokers.com/Universal/servlet/FlexStatementService.SendRequest",
"options": {
"response": {
"response": {
"responseFormat": "text"
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "t",
"value": "YOUR_FLEX_TOKEN"
},
{
"name": "q",
"value": "YOUR_QUERY_ID"
},
{
"name": "v",
"value": "3"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "b67bbf48-a427-4a96-b451-ceecbd24ca25",
"name": "2. Extract Reference Code",
"type": "n8n-nodes-base.code",
"position": [
880,
688
],
"parameters": {
"jsCode": "// Extract Reference Code from XML Response\n// Supports various response formats\n\nlet xml = '';\n\n// Check different possible structures\nif (typeof $input.item.json === 'string') {\n xml = $input.item.json;\n} else if ($input.item.json.body) {\n xml = $input.item.json.body;\n} else if ($input.item.json.data) {\n xml = $input.item.json.data;\n} else {\n // Fallback: convert entire JSON to String\n xml = JSON.stringify($input.item.json);\n}\n\n// Debug output\nconsole.log('XML Response:', xml);\n\n// Extract Reference Code\nconst match = xml.match(/<ReferenceCode>(.*?)<\\/ReferenceCode>/);\n\nif (match && match[1]) {\n return [{\n json: {\n referenceCode: match[1],\n token: 'YOUR_FLEX_TOKEN',\n debug_xml: xml.substring(0, 200)\n }\n }];\n} else {\n throw new Error('No Reference Code found. Response: ' + xml.substring(0, 500));\n}"
},
"typeVersion": 2
},
{
"id": "9bf9aef5-7a6b-4913-9144-bcf6989c35d4",
"name": "Wait 10 Seconds",
"type": "n8n-nodes-base.wait",
"notes": "IBKR needs time to generate",
"position": [
1104,
688
],
"parameters": {
"amount": 10
},
"typeVersion": 1.1
},
{
"id": "72cf587f-5f87-42e7-b599-4c6434b4f7af",
"name": "3. Download Report",
"type": "n8n-nodes-base.httpRequest",
"position": [
1328,
688
],
"parameters": {
"url": "https://gdcdyn.interactivebrokers.com/Universal/servlet/FlexStatementService.GetStatement",
"options": {
"response": {
"response": {
"responseFormat": "text"
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "t",
"value": "={{ $json.token }}"
},
{
"name": "q",
"value": "={{ $json.referenceCode }}"
},
{
"name": "v",
"value": "3"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "32848fdb-2b1a-49af-9ec1-263c59631660",
"name": "5. Split Trades",
"type": "n8n-nodes-base.splitOut",
"position": [
1776,
688
],
"parameters": {
"options": {},
"fieldToSplitOut": "FlexQueryResponse.FlexStatements.FlexStatement.Trades.Trade"
},
"typeVersion": 1
},
{
"id": "e7e7c804-d9ec-48c3-95a0-76cc8f9955c8",
"name": "6. Format Trade Fields",
"type": "n8n-nodes-base.set",
"position": [
2000,
688
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "b53e8a2a-e1b3-42c9-a38e-598df8461469",
"name": "tradeDate",
"type": "string",
"value": "={{ $json.tradeDate }}"
},
{
"id": "f986af54-8f07-47b9-abba-1a3304f64991",
"name": "symbol",
"type": "string",
"value": "={{ $json.symbol }}"
},
{
"id": "7ada5c33-76a9-4eb5-a6b5-e934c4d5428e",
"name": "quantity",
"type": "string",
"value": "={{ $json.quantity }}"
},
{
"id": "e087da0d-838c-44c6-9c16-d946a5977ffa",
"name": "buySell",
"type": "string",
"value": "={{ $json.buySell }}"
},
{
"id": "0828c1c4-f3cc-4616-a823-f02312918af6",
"name": "tradeID",
"type": "string",
"value": "={{ $json.tradeID }}"
},
{
"id": "6d37d15b-943c-49e6-9f54-f3b6b0a2a4e1",
"name": "dateTime",
"type": "string",
"value": "={{ $json.dateTime }}"
},
{
"id": "cbf18b22-7d5f-4b39-9013-2c04887fd500",
"name": "tradePrice",
"type": "string",
"value": "={{ $json.tradePrice }}"
},
{
"id": "4df82b35-8ecb-4519-beea-61ec962d2330",
"name": "currency",
"type": "string",
"value": "={{ $json.currency }}"
},
{
"id": "ad553c6c-9d45-4326-a71d-1973ed0cf1e4",
"name": "fxRateToBase",
"type": "string",
"value": "={{ $json.fxRateToBase }}"
},
{
"id": "57c32bbb-f9ea-43b5-ac8e-2333c2356180",
"name": "description",
"type": "string",
"value": "={{ $json.description }}"
},
{
"id": "8cf0f751-5177-4a5c-adfd-9b7ffb557621",
"name": "tradeMoney",
"type": "string",
"value": "={{ $json.tradeMoney }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9ae3859b-870f-42d7-9b28-81bb6d8d738c",
"name": "7. Save to Google Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
2224,
688
],
"parameters": {
"columns": {
"value": {
"symbol": "={{ $json.symbol }}",
"buySell": "={{ $json.buySell }}",
"tradeID": "={{ $json.tradeID }}",
"currency": "={{ $json.currency }}",
"dateTime": "={{ $json.dateTime }}",
"quantity": "={{ $json.quantity }}",
"tradeDate": "={{ $json.tradeDate }}",
"tradeMoney": "={{ $json.tradeMoney }}",
"tradePrice": "={{ $json.tradePrice }}",
"description": "={{ $json.description }}",
"fxRateToBase": "={{ $json.fxRateToBase }}"
},
"schema": [
{
"id": "tradeDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "tradeDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "dateTime",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "dateTime",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "symbol",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "symbol",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "description",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "quantity",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "quantity",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "buySell",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "buySell",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "tradePrice",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "tradePrice",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "tradeMoney",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "tradeMoney",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "currency",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "currency",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "fxRateToBase",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "fxRateToBase",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "tradeID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "tradeID",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"tradeID"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "id",
"value": "gid=0"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_GOOGLE_SHEET_ID"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "bba25f41-c980-43b7-a99e-8ce025e46154",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
-32
],
"parameters": {
"width": 480,
"height": 688,
"content": "# Automated IBKR Trade Report to Google Sheets Journal\n\n### How it works\n1. A daily schedule triggers a FlexStatement request to Interactive Brokers to start generating a trade report.\n2. The workflow extracts the reference code from IBKR's response, waits for the report to be ready, then downloads the Flex report XML.\n3. The XML is parsed and split into individual Trade records.\n4. Key fields (tradeDate, symbol, quantity, buySell, tradeID, price, money, currency, fxRateToBase) are normalized.\n5. Each trade is appended or updated in the configured Google Sheet, matching on tradeID to avoid duplicates and keep the journal current.\n\n### Setup steps\n- [ ] Set schedule to run at your desired time (default: 08:00)\n- [ ] Add or verify IBKR request token/reference parameters (Details in Sticky Note \"Setup Flex Query in Interactive Brokers\")\n- [ ] Adjust wait time if IBKR needs longer to generate reports\n- [ ] Select the Google Sheet and target sheet/tab\n- [ ] Connect Google Sheets OAuth2 account\n- [ ] Confirm column mapping and that tradeID is the matching column\n- [ ] Run a manual test to validate parsing and row updates"
},
"typeVersion": 1
},
{
"id": "25c0cc38-6bb9-4210-aab8-284efe39be3d",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
592,
560
],
"parameters": {
"color": 7,
"width": 464,
"height": 80,
"content": "## 1. Setup Flex Query in Interactive Brokers\n\n"
},
"typeVersion": 1
},
{
"id": "d32a94ec-d30e-47cb-92bd-4931a42d1cc4",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2128,
368
],
"parameters": {
"color": 7,
"width": 288,
"height": 272,
"content": "## 3. Save to Google Sheet\n\n### Enter your Google Sheet ID:\nIn node '7. Save to Google Sheet'\nReplace YOUR_GOOGLE_SHEET_ID\n\n### Connect Google credentials:\nIn node 7, select your Google OAuth2 credentials"
},
"typeVersion": 1
},
{
"id": "e66d7524-83c9-4370-91c9-0a4852897b5e",
"name": "Daily Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
432,
688
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * *"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "a6741176-6eec-44f1-8629-f08faeed1f17",
"name": "4. Convert XML to JSON",
"type": "n8n-nodes-base.xml",
"position": [
1552,
688
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "456a309d-ef03-475c-981e-69e9f8495057",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1104,
560
],
"parameters": {
"color": 7,
"width": 992,
"height": 80,
"content": "## 2. Download trade journal and format fields\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "3b095fed-0345-46a4-b8af-8d46185cc950",
"connections": {
"5. Split Trades": {
"main": [
[
{
"node": "6. Format Trade Fields",
"type": "main",
"index": 0
}
]
]
},
"Wait 10 Seconds": {
"main": [
[
{
"node": "3. Download Report",
"type": "main",
"index": 0
}
]
]
},
"3. Download Report": {
"main": [
[
{
"node": "4. Convert XML to JSON",
"type": "main",
"index": 0
}
]
]
},
"1. Request Flex Report": {
"main": [
[
{
"node": "2. Extract Reference Code",
"type": "main",
"index": 0
}
]
]
},
"4. Convert XML to JSON": {
"main": [
[
{
"node": "5. Split Trades",
"type": "main",
"index": 0
}
]
]
},
"6. Format Trade Fields": {
"main": [
[
{
"node": "7. Save to Google Sheet",
"type": "main",
"index": 0
}
]
]
},
"Daily Schedule Trigger": {
"main": [
[
{
"node": "1. Request Flex Report",
"type": "main",
"index": 0
}
]
]
},
"2. Extract Reference Code": {
"main": [
[
{
"node": "Wait 10 Seconds",
"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.
googleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow is aimed at traders who use Interactive Brokers. It automatically retrieves the trades made in IBKR on a daily basis and writes them to a Google Sheet, so that anyone can easily perform further analyses and statistics using the on-board tools.
Source: https://n8n.io/workflows/12151/ — 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.
This workflow is designed for venture capitalists, private equity professionals, investment analysts, and financial researchers who need to track private securities offerings and fundraising activitie
This workflow automatically monitors and tracks SEC Form D filings (private placement offerings) by fetching data from the SEC EDGAR database every 10 minutes during business hours and saving new fili
This workflow automates video distribution to 9 social platforms simultaneously using Blotato's API. It includes both a scheduled publisher (checks Google Sheets for videos marked "Ready") and a subwo
YogiAI. Uses googleSheets, googleSheetsTool, httpRequest, stopAndError. Scheduled trigger; 61 nodes.
This workflow monitors Google Calendar for events indicating that a customer will visit the company today or the next day, retrieves the required details, and sends reminder notifications to the relev