{"workflow":{"id":12539,"name":"Fetch reliable FX exchange rates with Frankfurter and open.er-api","views":11,"recentViews":0,"totalViews":11,"createdAt":"2026-01-07T10:24:21.680Z","description":"### This workflow fetches foreign exchange (FX) rates using multiple public APIs.\n\nIt validates all inputs, queries providers sequentially, and merges results into a single enforced output schema. The workflow is designed to guarantee complete coverage for the requested currencies. If full coverage cannot be achieved, it fails explicitly instead of returning partial data.\n\nAn optional `trim` flag allows the final output to be limited to only the currencies originally requested.\n\n## Who it’s for\nThis template is intended for developers and automation builders who need reliable FX rates as part of a larger workflow, such as reporting, pricing, analytics, or financial automation.\n\nIt can be used as a standalone workflow or reused as a sub-workflow via the Execute Workflow node.\n\n## How it works\nThe workflow starts by validating and normalizing the input parameters. An internal FX state is initialized and acts as the single source of truth throughout execution. Optional static rates can be defined at this stage and always take precedence over provider data.\n\nRates are fetched from a primary provider first. After each provider call, coverage is checked to determine whether all requested currencies have been resolved. If coverage is complete, the workflow stops early.\n\nIf some currencies are still missing, a secondary provider is queried. If coverage is still incomplete after the fallback provider, the workflow fails.\n\nWhen coverage is complete, the workflow optionally trims the output and returns the final FX payload.\n\n## How to set up\n- Provide a `baseCurrency` (ISO currency code).\n- Provide a `currencies` array containing the currencies to fetch (ISO currency code).\n- Set the `trim` flag to control whether the output is reduced to the requested currencies only.\n- Run the workflow manually for testing, or call it from another workflow using the Execute Workflow trigger.\n\n## How to customize the workflow\nYou can define static FX rates during the initialization step. Static rates always override provider results and can be used for fixed or pegged currencies.\n\nAdditional FX providers can be added by cloning the provider fetch nodes and connecting them to the existing coverage and error-handling logic.\n\n## Requirements\n- None. The workflow uses public APIs and does not require authentication or paid services.\n","workflow":{"nodes":[{"id":"9b76fbe7-d643-4f54-b334-bfca4491f887","name":"Set Currencies","type":"n8n-nodes-base.set","position":[176,-304],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e8fe115d-61b3-44f3-93b5-04be7661804c","name":"trim","type":"boolean","value":false},{"id":"1b14890b-8f18-4cbe-b7db-00d9107618cf","name":"baseCurrency","type":"string","value":"AED"},{"id":"aa73f2d7-6452-499f-a60c-5e6c07d5e3e2","name":"currencies","type":"array","value":"[\"USD\", \"EUR\", \"GBP\", \"JPY\", \"CHF\", \"AUD\", \"CAD\", \"NZD\", \"CNY\", \"HKD\", \"SGD\", \"KRW\", \"TWD\", \"INR\", \"AED\", \"SAR\", \"QAR\", \"KWD\", \"BHD\", \"OMR\", \"SEK\", \"NOK\", \"DKK\", \"PLN\", \"CZK\", \"HUF\", \"RON\", \"ILS\", \"TRY\", \"ZAR\", \"BRL\", \"MXN\", \"CLP\", \"COP\", \"THB\", \"IDR\", \"MYR\", \"PHP\", \"VND\"]"}]}},"typeVersion":3.4},{"id":"b070066b-cf98-4e19-88e3-11028547d74e","name":"If Valid Data","type":"n8n-nodes-base.if","position":[624,-208],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7f85de92-743b-4445-bc1b-3a626fe4e5fb","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.valid }}","rightValue":""}]}},"typeVersion":2.3},{"id":"cc9c9a7f-41d2-4825-9138-4bebf7d45a6a","name":"Stop and Error","type":"n8n-nodes-base.stopAndError","position":[848,-112],"parameters":{"errorMessage":"=Error: {{ $json.reason }}"},"typeVersion":1},{"id":"77db9040-880b-4a9c-aa92-8cbb2eae8cc9","name":"Frankfurter","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[1296,-304],"parameters":{"url":"https://api.frankfurter.dev/v1/latest","options":{},"sendQuery":true,"queryParameters":{"parameters":[{"name":"base","value":"={{ $json.fx.base }}"}]}},"retryOnFail":true,"typeVersion":4.3},{"id":"f2e4e674-d014-41df-9b14-7520e7dd40e5","name":"Normalize Frankfurter","type":"n8n-nodes-base.code","position":[1744,-400],"parameters":{"jsCode":"const res = $input.first().json;\n\nif (!res || typeof res !== 'object' || !res.rates) {\n  return [{\n    json: {\n      ok: false,\n      provider: 'frankfurter',\n      error: 'invalid_response'\n    }\n  }];\n}\n\nreturn [{\n  json: {\n    ok: true,\n    provider: 'frankfurter',\n    base: (res.base || '').toUpperCase(),\n    asOf: res.date || null,\n    rates: res.rates\n  }\n}];"},"typeVersion":2},{"id":"bdb88e3b-d12a-46eb-ae4b-5a308173d12c","name":"open.er-api.com","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[2416,-224],"parameters":{"url":"=https://open.er-api.com/v6/latest/{{$json.fx.base}}","options":{}},"retryOnFail":true,"typeVersion":4.3},{"id":"c327f7b4-1547-4c89-a2e6-98895601048d","name":"If base correct 1","type":"n8n-nodes-base.if","position":[1520,-304],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"30c6550f-e8b8-461c-94ad-c4acae27a08d","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.base }}","rightValue":"={{ $('Initialize Coverage Tracking').first().json.fx.base }}"}]}},"typeVersion":2.3},{"id":"585cb49c-716d-41bc-8f30-eae30b2e50b4","name":"If base correct  2","type":"n8n-nodes-base.if","position":[2640,-224],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"30c6550f-e8b8-461c-94ad-c4acae27a08d","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.base_code }}","rightValue":"={{ $('Merge Rates & Check Coverage (1)').first().json.fx.base }}"}]}},"typeVersion":2.3},{"id":"930d6e7c-1d0b-457a-a396-cf6b83c467d7","name":"Fetch FX Rates","type":"n8n-nodes-base.executeWorkflowTrigger","position":[176,-112],"parameters":{"workflowInputs":{"values":[{"name":"trim","type":"boolean"},{"name":"baseCurrency"},{"name":"currencies","type":"array"}]}},"typeVersion":1.1},{"id":"4a5f1c28-820c-49b6-be4b-7cee3f68b897","name":"Stop and Error3","type":"n8n-nodes-base.stopAndError","position":[3536,-176],"parameters":{"errorMessage":"Unable to fetch all currencies."},"typeVersion":1},{"id":"ef99aeb2-f5a0-472d-8a67-2575454e27fd","name":"Normalize open.er-api.com","type":"n8n-nodes-base.code","position":[2864,-320],"parameters":{"jsCode":"const res = $input.first().json;\n\nif (!res || res.result !== 'success' || !res.rates) {\n  return [{\n    json: {\n      ok: false,\n      provider: 'open.er-api.com',\n      error: res?.error_type || 'invalid_response'\n    }\n  }];\n}\n\nreturn [{\n  json: {\n    ok: true,\n    provider: 'open.er-api.com',\n    base: (res.base_code || '').toUpperCase(),\n    asOf: res.time_last_update_utc || res.time_last_update_unix || null,\n    rates: res.rates\n  }\n}];"},"typeVersion":2},{"id":"e170996f-5970-46ce-8bf1-8de7596e3cc5","name":"Handle Wrong Base 1","type":"n8n-nodes-base.code","position":[1744,-208],"parameters":{"jsCode":"return [{\n  json: {\n    ok: false,\n    provider: 'frankfurter',\n    error: 'invalid_basecurrency'\n  }\n}];"},"typeVersion":2},{"id":"e2e8d53f-a585-4a1c-b1f6-fae93fbe1f92","name":"Handle Wrong Base 2","type":"n8n-nodes-base.code","position":[2864,-128],"parameters":{"jsCode":"return [{\n  json: {\n    ok: false,\n    provider: 'open.er-api.com',\n    error: 'invalid_basecurrency'\n  }\n}];"},"typeVersion":2},{"id":"9f4e28ec-480c-4581-8d86-b6a4b6d47502","name":"Trim","type":"n8n-nodes-base.code","position":[3760,-464],"parameters":{"jsCode":"// Source of truth: Create List\nconst req = $('Validate & Normalize Inputs').first().json;\n\nconst requestedBase = String(req.baseCurrency).toUpperCase();\nconst requestedCurrencies = Array.isArray(req.currencies)\n  ? req.currencies.map(c => String(c).toUpperCase())\n  : [];\n\n// Current FX payload\nconst fx = $input.first().json.fx || {};\nconst rates = fx.rates || {};\nconst sources = fx.sources || {};\n\n// Prepare trimmed objects\nconst trimmedRates = {};\nconst trimmedSources = {};\n\n// Always include base\ntrimmedRates[requestedBase] = 1;\nif (sources[requestedBase]) {\n  trimmedSources[requestedBase] = sources[requestedBase];\n}\n\n// Include only requested currencies\nfor (const sym of requestedCurrencies) {\n  if (typeof rates[sym] === 'number') {\n    trimmedRates[sym] = rates[sym];\n    if (sources[sym]) {\n      trimmedSources[sym] = sources[sym];\n    }\n  }\n}\n\nreturn [\n  {\n    json: {\n      ...$input.first().json,\n      fx: {\n        base: requestedBase,\n        asOf: fx.asOf || null,\n        rates: trimmedRates,\n        sources: trimmedSources\n      }\n    }\n  }\n];"},"typeVersion":2},{"id":"f22fcecd-6344-44af-a487-b82dc34e1498","name":"If Trim","type":"n8n-nodes-base.if","position":[3536,-400],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"d99e26e3-7469-4528-a0c6-82aa4737177c","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $('Validate & Normalize Inputs').first().json.trim }}","rightValue":""}]}},"typeVersion":2.3},{"id":"ec7a2f04-a6c8-47b0-bf16-2ceb0fd7eb62","name":"Manual Trigger (Example)","type":"n8n-nodes-base.manualTrigger","position":[-48,-304],"parameters":{},"typeVersion":1},{"id":"bf019fea-6cc2-4076-b16b-a6cf4c051d6c","name":"Validate & Normalize Inputs","type":"n8n-nodes-base.code","position":[400,-208],"parameters":{"jsCode":"// Get base currency from trigger\nconst trim = $input.first().json.trim;\nconst baseCurrencyRaw = $input.first().json.baseCurrency;\nconst baseCurrency = baseCurrencyRaw?.toUpperCase();\n\nconst currenciesRaw = $input.first().json.currencies;\n\n// Preparing return object\nlet object = {\n  valid: false,\n  reason: '',\n  trim,\n  baseCurrency,\n  currencies: currenciesRaw\n};\n\nif (!baseCurrency || typeof baseCurrency !== 'string') {\n  object.reason = 'baseCurrency is missing or invalid';\n} else if (!Array.isArray(currenciesRaw)) {\n  object.reason = 'currencies is not an array';\n} else {\n    // Check presence\n  const currencies = currenciesRaw.map(c => c.toUpperCase());\n  const hasBase = currencies.includes(baseCurrency);\n  const filteredCurrencies = hasBase\n    ? currencies.filter((c) => c !== baseCurrency)\n    : currencies;\n  object.valid = true;\n  object.currencies = filteredCurrencies;\n}\n\nreturn [\n  {\n    json: object\n  }\n];"},"typeVersion":2},{"id":"528a4062-c9a8-4924-b859-3b5aa377ebc1","name":"Initialize FX State + Static Rates","type":"n8n-nodes-base.code","position":[848,-304],"parameters":{"jsCode":"const base = $input.first().json.baseCurrency?.toUpperCase();\n\nconst staticRates = {};\nconst staticMeta = {};\n\n// only apply when base is USD\nif (base === 'USD') {\n  // optional\n  // staticRates.AED = 3.6725;\n  // staticMeta.AED = 'static_usd_peg';\n  // staticRates.SAR = 3.75;\n  // staticMeta.SAR = 'static_usd_peg';\n  // staticRates.QAR = 3.64;\n  // staticMeta.QAR = 'static_usd_peg';\n}\n\nreturn [{\n  json: {\n    ...$input.first().json,\n    fx: {\n      base,\n      asOf: new Date().toISOString(),\n      rates: staticRates,\n      sources: staticMeta\n    }\n  }\n}];"},"typeVersion":2},{"id":"030de89f-2d67-425f-819b-5f7daf12a696","name":"Initialize Coverage Tracking","type":"n8n-nodes-base.code","position":[1072,-304],"parameters":{"jsCode":"function isRate(x) {\n  return typeof x === 'number' && Number.isFinite(x) && x > 0;\n}\n\nconst req = $('Validate & Normalize Inputs').first().json;     // source of truth\nconst requestedBase = req.baseCurrency;        // already uppercase\nconst requestedSymbols = req.currencies || []; // already excludes base\n\nconst runningFx = $input.first().json.fx || { base: requestedBase, rates: {}, sources: {}, asOf: null };\nconst rates = runningFx.rates || {};\n\nconst missing = [];\nconst invalid = [];\n\nfor (const sym of requestedSymbols) {\n  const v = rates[sym];\n  if (v == null) missing.push(sym);\n  else if (!isRate(v)) invalid.push(sym);\n}\n\nreturn [{\n  json: {\n    fx: {\n      base: requestedBase,\n      asOf: runningFx.asOf || new Date().toISOString(),\n      rates: rates,\n      sources: runningFx.sources || {}\n    },\n    missing,\n    invalid,\n    complete: missing.length === 0 && invalid.length === 0\n  }\n}];\n"},"typeVersion":2},{"id":"c8922d5e-2baf-4e5e-b29e-02a9596f4608","name":"Merge Rates & Check Coverage (1)","type":"n8n-nodes-base.code","position":[1968,-304],"parameters":{"jsCode":"function isRate(x) {\n  return typeof x === 'number' && Number.isFinite(x) && x > 0;\n}\n\nconst requestedBase = $('Validate & Normalize Inputs').first().json.baseCurrency.toUpperCase();\nconst requestedSymbols = $('Validate & Normalize Inputs').first().json.currencies; // already excludes base\n\nconst runningFx = $('Initialize Coverage Tracking').first().json.fx;\nconst provider = $input.first().json; // normalized provider output\n\n// start with running\nconst mergedRates = { ...(runningFx.rates || {}) };\nconst mergedSources = { ...(runningFx.sources || {}) };\n\n// only merge provider if ok and base matches\nif (provider.ok && provider.base === requestedBase && provider.rates && typeof provider.rates === 'object') {\n  for (const [k, v] of Object.entries(provider.rates)) {\n    const sym = k.toUpperCase();\n    if (!isRate(v)) continue;\n\n    // do not overwrite existing rate (static wins if already set)\n    if (mergedRates[sym] == null) {\n      mergedRates[sym] = v;\n      mergedSources[sym] = provider.provider;\n    }\n  }\n}\n\n// now check coverage\nconst missing = [];\nconst invalid = [];\n\nfor (const sym of requestedSymbols) {\n  const v = mergedRates[sym];\n  if (v == null) missing.push(sym);\n  else if (!isRate(v)) invalid.push(sym);\n}\n\nconst complete = missing.length === 0 && invalid.length === 0;\n\nreturn [{\n  json: {\n    fx: {\n      base: requestedBase,\n      asOf: provider.asOf || runningFx.asOf,\n      rates: mergedRates,\n      sources: mergedSources\n    },\n    complete,\n    missing,\n    invalid\n  }\n}];"},"typeVersion":2},{"id":"4cd57cab-a81c-4a2a-8594-bc5bf062b91c","name":"Merge Rates & Check Coverage (2)","type":"n8n-nodes-base.code","position":[3088,-224],"parameters":{"jsCode":"function isRate(x) {\n  return typeof x === 'number' && Number.isFinite(x) && x > 0;\n}\n\nconst requestedBase = $('Validate & Normalize Inputs').first().json.baseCurrency.toUpperCase();\nconst requestedSymbols = $('Validate & Normalize Inputs').first().json.currencies; // already excludes base\n\nconst runningFx = $('Merge Rates & Check Coverage (1)').first().json.fx || { base: requestedBase, rates: {}, sources: {} };\nconst provider = $input.first().json; // normalized provider output\n\n// start with running\nconst mergedRates = { ...(runningFx.rates || {}) };\nconst mergedSources = { ...(runningFx.sources || {}) };\n\n// only merge provider if ok and base matches\nif (provider.ok && provider.base === requestedBase && provider.rates && typeof provider.rates === 'object') {\n  for (const [k, v] of Object.entries(provider.rates)) {\n    const sym = k.toUpperCase();\n    if (!isRate(v)) continue;\n\n    // do not overwrite existing rate (static wins if already set)\n    if (mergedRates[sym] == null) {\n      mergedRates[sym] = v;\n      mergedSources[sym] = provider.provider;\n    }\n  }\n}\n\n// now check coverage\nconst missing = [];\nconst invalid = [];\n\nfor (const sym of requestedSymbols) {\n  const v = mergedRates[sym];\n  if (v == null) missing.push(sym);\n  else if (!isRate(v)) invalid.push(sym);\n}\n\nconst complete = missing.length === 0 && invalid.length === 0;\n\nreturn [{\n  json: {\n    fx: {\n      base: requestedBase,\n      asOf: provider.asOf || runningFx.asOf,\n      rates: mergedRates,\n      sources: mergedSources\n    },\n    complete,\n    missing,\n    invalid\n  }\n}];"},"typeVersion":2},{"id":"c357635b-f4e8-4c6b-819c-f79442792da3","name":"Coverage Complete 1?","type":"n8n-nodes-base.if","position":[2192,-304],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"36c63465-3ccb-4ab4-a43b-785468cdefa0","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.complete }}","rightValue":""}]}},"typeVersion":2.3},{"id":"77e273fc-fc8d-4716-8192-366f855c7a26","name":"Coverage Complete 2?","type":"n8n-nodes-base.if","position":[3312,-224],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"36c63465-3ccb-4ab4-a43b-785468cdefa0","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.complete }}","rightValue":""}]}},"typeVersion":2.3},{"id":"9072a67f-0e25-4d4a-9d06-04e2d0027ec7","name":"Final Output","type":"n8n-nodes-base.noOp","position":[3984,-400],"parameters":{},"typeVersion":1},{"id":"5a14b24b-277d-40b5-b1be-f117d56c6330","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-240,-1424],"parameters":{"width":580,"height":894,"content":"# Multi-provider FX Rates Fetcher\nThis workflow fetches foreign exchange (FX) rates for a configurable base currency using multiple public APIs.\n\nIt is designed to guarantee complete coverage for the requested currencies. The workflow validates all inputs, queries providers sequentially, and merges results into a single enforced output schema. If full coverage cannot be achieved, the workflow fails instead of returning partial data.\n\nAn optional trim flag allows the final output to be limited to only the currencies originally requested.\n\n## How it works\n1. The workflow starts by validating inputs (`baseCurrency` and `currencies`), it removes the base currency from the target list and ensure that the input is valid.\n2. An internal FX is then initialized. This state acts as the single source of truth and can optionally include static rates, which always take precedence over provider data.\n3. Rates are fetched from a primary provider and merged into the FX state if the response base currency matches the requested base. Coverage is checked after each provider call. If all requested currencies are resolved, the workflow stops early.\n4. If coverage is incomplete, a secondary provider is queried for the remaining currencies. If coverage is still incomplete after the fallback provider, the workflow fails.\n5. If coverage is complete, the workflow optional.\n\n## Setup\n* [ ] Provide `baseCurrency` (ISO code) and `currencies` (array of ISO codes).\n* [ ] Enable the `trim` option if you want the output limited to requested currencies only.\n* [ ] Run manually or replace the trigger with a schedule, webhook, or another workflow.\n* [ ] Edit the static rates block if you need to inject fixed peg rates (optional).\n\n## Requirements\n* None. The workflow uses public APIs and does not require authentication or paid services."},"typeVersion":1},{"id":"b97fd36c-9e86-4bfa-8f1d-5a15ce47c232","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-240,-464],"parameters":{"color":3,"width":576,"height":496,"content":"## Inputs\n* `trim` (boolean)\n* `baseCurrency` (string, e.g. \"EUR\")\n* `currencies` (array of string ISO currency codes, e.g [\"USD\",\"EUR\",\"IDR\",\"AED\"])\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n### Use Manual Trigger or\n### Call from another workflow"},"typeVersion":1},{"id":"624b0a2b-ff5b-4e49-83cc-2ce2b9b000a5","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[752,-560],"parameters":{"color":6,"width":288,"height":416,"content":"## Optional static rates\n* You can define fixed FX rates here. Static rates always override provider results.\n\ne.g. \nif (base === 'USD') {\n   staticRates.AED = 3.6725;\n   staticMeta.AED = 'static_usd_peg';\n}"},"typeVersion":1},{"id":"f848ff8c-83d2-4622-aeee-64a4f1cd3e82","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[2352,-464],"parameters":{"color":6,"width":1120,"height":512,"content":"## Optional expand providers\n* Clone this nodes to expand your fetcher with another provider and connect the clones to Stop and Error3 node."},"typeVersion":1}],"connections":{"Trim":{"main":[[{"node":"Final Output","type":"main","index":0}]]},"If Trim":{"main":[[{"node":"Trim","type":"main","index":0}],[{"node":"Final Output","type":"main","index":0}]]},"Frankfurter":{"main":[[{"node":"If base correct 1","type":"main","index":0}]]},"If Valid Data":{"main":[[{"node":"Initialize FX State + Static Rates","type":"main","index":0}],[{"node":"Stop and Error","type":"main","index":0}]]},"Fetch FX Rates":{"main":[[{"node":"Validate & Normalize Inputs","type":"main","index":0}]]},"Set Currencies":{"main":[[{"node":"Validate & Normalize Inputs","type":"main","index":0}]]},"open.er-api.com":{"main":[[{"node":"If base correct  2","type":"main","index":0}]]},"If base correct 1":{"main":[[{"node":"Normalize Frankfurter","type":"main","index":0}],[{"node":"Handle Wrong Base 1","type":"main","index":0}]]},"If base correct  2":{"main":[[{"node":"Normalize open.er-api.com","type":"main","index":0}],[{"node":"Handle Wrong Base 2","type":"main","index":0}]]},"Handle Wrong Base 1":{"main":[[{"node":"Merge Rates & Check Coverage (1)","type":"main","index":0}]]},"Handle Wrong Base 2":{"main":[[{"node":"Merge Rates & Check Coverage (2)","type":"main","index":0}]]},"Coverage Complete 1?":{"main":[[{"node":"If Trim","type":"main","index":0}],[{"node":"open.er-api.com","type":"main","index":0}]]},"Coverage Complete 2?":{"main":[[{"node":"If Trim","type":"main","index":0}],[{"node":"Stop and Error3","type":"main","index":0}]]},"Normalize Frankfurter":{"main":[[{"node":"Merge Rates & Check Coverage (1)","type":"main","index":0}]]},"Manual Trigger (Example)":{"main":[[{"node":"Set Currencies","type":"main","index":0}]]},"Normalize open.er-api.com":{"main":[[{"node":"Merge Rates & Check Coverage (2)","type":"main","index":0}]]},"Validate & Normalize Inputs":{"main":[[{"node":"If Valid Data","type":"main","index":0}]]},"Initialize Coverage Tracking":{"main":[[{"node":"Frankfurter","type":"main","index":0}]]},"Merge Rates & Check Coverage (1)":{"main":[[{"node":"Coverage Complete 1?","type":"main","index":0}]]},"Merge Rates & Check Coverage (2)":{"main":[[{"node":"Coverage Complete 2?","type":"main","index":0}]]},"Initialize FX State + Static Rates":{"main":[[{"node":"Initialize Coverage Tracking","type":"main","index":0}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":28,"nodeTypes":{"n8n-nodes-base.if":{"count":6},"n8n-nodes-base.set":{"count":1},"n8n-nodes-base.code":{"count":10},"n8n-nodes-base.noOp":{"count":1},"n8n-nodes-base.stickyNote":{"count":4},"n8n-nodes-base.httpRequest":{"count":2},"n8n-nodes-base.stopAndError":{"count":2},"n8n-nodes-base.manualTrigger":{"count":1},"n8n-nodes-base.executeWorkflowTrigger":{"count":1}}},"status":"published","readyToDemo":null,"user":{"name":"Matchaccino Studio","username":"matchaccinostudio","bio":"","verified":false,"links":["https://matchaccino.ai/"],"avatar":"https://gravatar.com/avatar/060b0e856137b1d2715265f0b692c2f0ee2a93bf505e0be717b8134eca0a9bb6?r=pg&d=retro&size=200"},"nodes":[{"id":19,"icon":"file:httprequest.svg","name":"n8n-nodes-base.httpRequest","codex":{"data":{"alias":["API","Request","URL","Build","cURL"],"resources":{"generic":[{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/","icon":"📈","label":"Automatically pulling and visualizing data with n8n"},{"url":"https://n8n.io/blog/learn-how-to-automatically-cross-post-your-content-with-n8n/","icon":"✍️","label":"Learn how to automatically cross-post your content with n8n"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/","icon":"🛳","label":"Running n8n on ships: An interview with Maranics"},{"url":"https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/","icon":" 🪢","label":"What are APIs and how to use them with no code"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/world-poetry-day-workflow/","icon":"📜","label":"Celebrating World Poetry Day with a daily poem in Telegram"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/automate-designs-with-bannerbear-and-n8n/","icon":"🎨","label":"Automate Designs with Bannerbear and n8n"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/","icon":"📱","label":"Building an expense tracking app in 10 minutes"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/how-to-use-the-http-request-node-the-swiss-army-knife-for-workflow-automation/","icon":"🧰","label":"How to use the HTTP Request Node - The Swiss Army Knife for Workflow Automation"},{"url":"https://n8n.io/blog/learn-how-to-use-webhooks-with-mattermost-slash-commands/","icon":"🦄","label":"Learn how to use webhooks with Mattermost slash commands"},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/","icon":"📈","label":"A low-code bitcoin ticker built with QuestDB and n8n.io"},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/automations-for-activists/","icon":"✨","label":"How Common Knowledge use workflow automation for activism"},{"url":"https://n8n.io/blog/creating-scheduled-text-affirmations-with-n8n/","icon":"🤟","label":"Creating scheduled text affirmations with n8n"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"output\"]","defaults":{"name":"HTTP Request","color":"#0004F5"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MCAyMEM0MCA4Ljk1MzE0IDMxLjA0NjkgMCAyMCAwQzguOTUzMTQgMCAwIDguOTUzMTQgMCAyMEMwIDMxLjA0NjkgOC45NTMxNCA0MCAyMCA0MEMzMS4wNDY5IDQwIDQwIDMxLjA0NjkgNDAgMjBaTTIwIDM2Ljk0NThDMTguODg1MiAzNi45NDU4IDE3LjEzNzggMzUuOTY3IDE1LjQ5OTggMzIuNjk4NUMxNC43OTY0IDMxLjI5MTggMTQuMTk2MSAyOS41NDMxIDEzLjc1MjYgMjcuNjg0N0gyNi4xODk4QzI1LjgwNDUgMjkuNTQwMyAyNS4yMDQ0IDMxLjI5MDEgMjQuNTAwMiAzMi42OTg1QzIyLjg2MjIgMzUuOTY3IDIxLjExNDggMzYuOTQ1OCAyMCAzNi45NDU4Wk0xMi45MDY0IDIwQzEyLjkwNjQgMjEuNjA5NyAxMy4wMDg3IDIzLjE2NCAxMy4yMDAzIDI0LjYzMDVIMjYuNzk5N0MyNi45OTEzIDIzLjE2NCAyNy4wOTM2IDIxLjYwOTcgMjcuMDkzNiAyMEMyNy4wOTM2IDE4LjM5MDMgMjYuOTkxMyAxNi44MzYgMjYuNzk5NyAxNS4zNjk1SDEzLjIwMDNDMTMuMDA4NyAxNi44MzYgMTIuOTA2NCAxOC4zOTAzIDEyLjkwNjQgMjBaTTIwIDMuMDU0MTlDMjEuMTE0OSAzLjA1NDE5IDIyLjg2MjIgNC4wMzA3OCAyNC41MDAxIDcuMzAwMzlDMjUuMjA2NiA4LjcxNDA4IDI1LjgwNzIgMTAuNDA2NyAyNi4xOTIgMTIuMzE1M0gxMy43NTAxQzE0LjE5MzMgMTAuNDA0NyAxNC43OTQyIDguNzEyNTQgMTUuNDk5OCA3LjMwMDY0QzE3LjEzNzcgNC4wMzA4MyAxOC44ODUxIDMuMDU0MTkgMjAgMy4wNTQxOVpNMzAuMTQ3OCAyMEMzMC4xNDc4IDE4LjQwOTkgMzAuMDU0MyAxNi44NjE3IDI5LjgyMjcgMTUuMzY5NUgzNi4zMDQyQzM2LjcyNTIgMTYuODQyIDM2Ljk0NTggMTguMzk2NCAzNi45NDU4IDIwQzM2Ljk0NTggMjEuNjAzNiAzNi43MjUyIDIzLjE1OCAzNi4zMDQyIDI0LjYzMDVIMjkuODIyN0MzMC4wNTQzIDIzLjEzODMgMzAuMTQ3OCAyMS41OTAxIDMwLjE0NzggMjBaTTI2LjI3NjcgNC4yNTUxMkMyNy42MzY1IDYuMzYwMTkgMjguNzExIDkuMTMyIDI5LjM3NzQgMTIuMzE1M0gzNS4xMDQ2QzMzLjI1MTEgOC42NjggMzAuMTA3IDUuNzgzNDYgMjYuMjc2NyA0LjI1NTEyWk0xMC42MjI2IDEyLjMxNTNINC44OTI5M0M2Ljc1MTQ3IDguNjY3ODQgOS44OTM1MSA1Ljc4MzQxIDEzLjcyMzIgNC4yNTUxM0MxMi4zNjM1IDYuMzYwMjEgMTEuMjg5IDkuMTMyMDEgMTAuNjIyNiAxMi4zMTUzWk0zLjA1NDE5IDIwQzMuMDU0MTkgMjEuNjAzIDMuMjc3NDMgMjMuMTU3NSAzLjY5NDg0IDI0LjYzMDVIMTAuMTIxN0M5Ljk0NjE5IDIzLjE0MiA5Ljg1MjIyIDIxLjU5NDMgOS44NTIyMiAyMEM5Ljg1MjIyIDE4LjQwNTcgOS45NDYxOSAxNi44NTggMTAuMTIxNyAxNS4zNjk1SDMuNjk0ODRDMy4yNzc0MyAxNi44NDI1IDMuMDU0MTkgMTguMzk3IDMuMDU0MTkgMjBaTTI2LjI3NjYgMzUuNzQyN0MyNy42MzY1IDMzLjYzOTMgMjguNzExIDMwLjg2OCAyOS4zNzc0IDI3LjY4NDdIMzUuMTA0NkMzMy4yNTEgMzEuMzMyMiAzMC4xMDY4IDM0LjIxNzkgMjYuMjc2NiAzNS43NDI3Wk0xMy43MjM0IDM1Ljc0MjdDOS44OTM2OSAzNC4yMTc5IDYuNzUxNTUgMzEuMzMyNCA0Ljg5MjkzIDI3LjY4NDdIMTAuNjIyNkMxMS4yODkgMzAuODY4IDEyLjM2MzUgMzMuNjM5MyAxMy43MjM0IDM1Ljc0MjdaIiBmaWxsPSIjM0E0MkU5Ii8+Cjwvc3ZnPgo="},"displayName":"HTTP Request","typeVersion":4,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":20,"icon":"fa:map-signs","name":"n8n-nodes-base.if","codex":{"data":{"alias":["Router","Filter","Condition","Logic","Boolean","Branch"],"details":"The IF node can be used to implement binary conditional logic in your workflow. You can set up one-to-many conditions to evaluate each item of data being inputted into the node. That data will either evaluate to TRUE or FALSE and route out of the node accordingly.\n\nThis node has multiple types of conditions: Bool, String, Number, and Date & Time.","resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/create-a-toxic-language-detector-for-telegram/","icon":"🤬","label":"Create a toxic language detector for Telegram in 4 step"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/automation-for-maintainers-of-open-source-projects/","icon":"🏷️","label":"How to automatically manage contributions to open-source projects"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.if/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"transform\"]","defaults":{"name":"If","color":"#408000"},"iconData":{"icon":"map-signs","type":"icon"},"displayName":"If","typeVersion":2,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":26,"icon":"fa:arrow-right","name":"n8n-nodes-base.noOp","codex":{"data":{"alias":["nothing"],"resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/create-a-toxic-language-detector-for-telegram/","icon":"🤬","label":"Create a toxic language detector for Telegram in 4 step"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.noop/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"organization\"]","defaults":{"name":"No Operation, do nothing","color":"#b0b0b0"},"iconData":{"icon":"arrow-right","type":"icon"},"displayName":"No Operation, do nothing","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":38,"icon":"fa:pen","name":"n8n-nodes-base.set","codex":{"data":{"alias":["Set","JS","JSON","Filter","Transform","Map"],"resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/","icon":"📈","label":"Automatically pulling and visualizing data with n8n"},{"url":"https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/","icon":"📡","label":"Database Monitoring and Alerting with n8n"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/","icon":"📱","label":"Building an expense tracking app in 10 minutes"},{"url":"https://n8n.io/blog/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/","icon":"📹","label":"The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/","icon":"🧰","label":"Learn to Build Powerful API Endpoints Using Webhooks"},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/","icon":"📈","label":"A low-code bitcoin ticker built with QuestDB and n8n.io"},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Data Transformation"]}}},"group":"[\"input\"]","defaults":{"name":"Edit Fields"},"iconData":{"icon":"pen","type":"icon"},"displayName":"Edit Fields (Set)","typeVersion":3,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":528,"icon":"fa:exclamation-triangle","name":"n8n-nodes-base.stopAndError","codex":{"data":{"alias":["Throw error","Error","Exception"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.stopanderror/"}]},"categories":["Core Nodes","Utility"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"input\"]","defaults":{"name":"Stop and Error","color":"#ff0000"},"iconData":{"icon":"exclamation-triangle","type":"icon"},"displayName":"Stop and Error","typeVersion":1,"nodeCategories":[{"id":7,"name":"Utility"},{"id":9,"name":"Core Nodes"}]},{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":834,"icon":"file:code.svg","name":"n8n-nodes-base.code","codex":{"data":{"alias":["cpde","Javascript","JS","Python","Script","Custom Code","Function"],"details":"The Code node allows you to execute JavaScript in your workflow.","resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Code"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Code","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":837,"icon":"fa:sign-out-alt","name":"n8n-nodes-base.executeWorkflowTrigger","codex":{"data":{"resources":{"generic":[],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflowtrigger/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"trigger\"]","defaults":{"name":"When Executed by Another Workflow","color":"#ff6d5a"},"iconData":{"icon":"sign-out-alt","type":"icon"},"displayName":"Execute Workflow Trigger","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":838,"icon":"fa:mouse-pointer","name":"n8n-nodes-base.manualTrigger","codex":{"data":{"resources":{"generic":[],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.manualworkflowtrigger/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"trigger\"]","defaults":{"name":"When clicking ‘Execute workflow’","color":"#909298"},"iconData":{"icon":"mouse-pointer","type":"icon"},"displayName":"Manual Trigger","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]}],"categories":[{"id":5,"name":"Engineering"}],"image":[]}}