{
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 8
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        8192,
        1856
      ],
      "id": "1cd5af1d-3a4b-4b16-815e-25711f261b0a",
      "name": "Every 8 Hours"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "YOUR_FAILEDITEMS_SHEET_ID",
          "mode": "list",
          "cachedResultName": "\ud83d\udea98-hour Retries",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "FailedItems",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit#gid=0"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "position": [
        8432,
        1856
      ],
      "id": "86f34bc2-21cb-4e1e-9559-519059e878f2",
      "name": "Read FailedItems",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Prepare Items: assign indices, filter, sort DESC\nconst items = $input.all().map((item, index) => ({\n  json: {\n    ...item.json,\n    _rowIndex: index + 2  // row 1 = header\n  }\n}));\n\n// Filter: status=pending_retry AND is_retryable=true (handles string or boolean)\nconst filtered = items.filter(item =>\n  item.json.status === 'pending_retry' &&\n  (item.json.is_retryable === 'true' || item.json.is_retryable === true)\n);\n\n// Sort by _rowIndex DESC (prevent row shift on delete)\nreturn filtered.sort((a, b) => b.json._rowIndex - a.json._rowIndex);"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        8552,
        1856
      ],
      "id": "prepare-items-node-001",
      "name": "Prepare Items"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        8912,
        1856
      ],
      "id": "0e25f3e3-d415-4075-b602-5a454a86d9e5",
      "name": "Loop Over Items"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "version": 2,
            "combinator": "and"
          },
          "conditions": [
            {
              "leftValue": "={{ Number($json.retry_count) }}",
              "rightValue": 3,
              "operator": {
                "type": "number",
                "operation": "lt"
              }
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        9152,
        1856
      ],
      "id": "d63b6b8f-47c1-470d-8811-a3097e647921",
      "name": "retry_count < 3?"
    },
    {
      "parameters": {
        "jsCode": "// Calculate Retry Delay based on expected Groq requests\n// Groq has 5 req/min limit - this is the bottleneck\n// Google calls happen in parallel with separate limit, so we ignore them\n\n// Parse LLM cost estimate from JSON column\nconst llmCost = JSON.parse($json.retry_params || '{}');\nconst expectedGroq = Number(llmCost.groq) || 3;\nconst GROQ_REQUESTS_PER_MINUTE = 5;\n\n// Time needed for Groq calls + 20% safety margin\n// Formula: (expected_calls / rate_limit) * 60 seconds * 1.2 safety\nconst delaySeconds = Math.max(60, Math.round((expectedGroq / GROQ_REQUESTS_PER_MINUTE) * 60 * 1.2));\n\nreturn [{\n  json: {\n    ...$json,\n    delay_seconds: delaySeconds\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        9392,
        1824
      ],
      "id": "a1b57935-45b2-4efa-9d04-e4edb4eb286a",
      "name": "Calculate Retry Delay"
    },
    {
      "parameters": {
        "amount": "={{ $('Loop Over Items').context['currentRunIndex'] === 0 ? 0 : $json.delay_seconds }}"
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        9600,
        1824
      ],
      "id": "c5b4b9f3-1205-478e-bff7-690bacb38c2b",
      "name": "Wait Before Retry"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://YOUR_N8N_INSTANCE.up.railway.app/api/v1/executions/{{ $json.execution_id }}/retry",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        9792,
        1824
      ],
      "id": "4c1ed191-fad3-4f79-9f91-a341b8f1a23a",
      "name": "Execute Retry via API",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Extract ID - Step 1 of polling sequence\n// Extracts execution ID from API response and initializes polling state\n// No credentials needed - just data manipulation\n\nconst item = $('Loop Over Items').item.json;\nconst apiResponse = $input.first().json;\nconst newRetryCount = Number(item.retry_count || 0) + 1;\n\n// Retry API returns id at root level, not inside data\nconst newExecutionId = apiResponse.id;\n\nreturn [{\n  json: {\n    ...item,\n    retry_count: newRetryCount,\n    last_retry_at: new Date().toISOString(),\n    new_execution_id: newExecutionId || null,\n    api_call_succeeded: !!newExecutionId,\n    poll_count: 0,\n    is_done: !newExecutionId  // If no ID, we're done (failed to start)\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        10000,
        1824
      ],
      "id": "extract-id-wait-node-001",
      "name": "Extract ID"
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://YOUR_N8N_INSTANCE.up.railway.app/api/v1/executions/{{ $json.new_execution_id }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        10208,
        1824
      ],
      "id": "poll-execution-status-node-001",
      "name": "Poll Execution Status",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Evaluate Poll - Check if execution is finished and increment counter\n// Sets is_done flag for loop control\n\nconst itemData = $('Extract ID').item.json;\nconst pollResponse = $input.first().json;\nconst currentPollCount = Number(itemData.poll_count) || 0;\n\n// If API call failed (no execution ID), preserve the failed state\nif (!itemData.api_call_succeeded) {\n  return [{\n    json: {\n      ...itemData,\n      poll_count: currentPollCount + 1,\n      is_done: true,\n      execution_status: 'api_failed',\n      execution_finished: false\n    }\n  }];\n}\n\n// Check if execution is finished (success, error, or finished flag)\nconst executionStatus = pollResponse.status || 'unknown';\nconst isFinished = pollResponse.finished === true;\nconst isDone = executionStatus === 'success' || executionStatus === 'error' || isFinished;\n\nreturn [{\n  json: {\n    ...itemData,\n    poll_count: currentPollCount + 1,\n    is_done: isDone,\n    execution_status: executionStatus,\n    execution_finished: isFinished\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        10416,
        1824
      ],
      "id": "evaluate-poll-node-001",
      "name": "Evaluate Poll"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "continue-polling-condition-1",
              "leftValue": "={{ $json.is_done }}",
              "rightValue": false,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            },
            {
              "id": "continue-polling-condition-2",
              "leftValue": "={{ $json.poll_count }}",
              "rightValue": 30,
              "operator": {
                "type": "number",
                "operation": "lt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        10624,
        1824
      ],
      "id": "should-continue-polling-node-001",
      "name": "Should Continue Polling?"
    },
    {
      "parameters": {
        "amount": 10
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        10624,
        1640
      ],
      "id": "wait-10s-node-001",
      "name": "Wait 10s"
    },
    {
      "parameters": {
        "jsCode": "// Evaluate Result - Final evaluation before routing to success/failure\n// Determines retry_success based on final execution status\n\nconst itemData = $json;\n\n// Check if retry truly succeeded\nconst executionStatus = itemData.execution_status || 'unknown';\nconst isFinished = itemData.execution_finished === true;\nconst retrySuccess = executionStatus === 'success' && isFinished;\n\n// Handle timeout case (30 polls = 5 minutes)\nconst timedOut = itemData.poll_count >= 30 && !itemData.is_done;\nconst finalStatus = timedOut ? 'timeout' : executionStatus;\n\nreturn [{\n  json: {\n    ...itemData,\n    retry_success: retrySuccess,\n    execution_status: finalStatus\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        10832,
        1920
      ],
      "id": "evaluate-result-node-001",
      "name": "Evaluate Result"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "b2f3a4c5-retry-success-condition",
              "leftValue": "={{ $json.execution_status }}",
              "rightValue": "success",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        11040,
        1920
      ],
      "id": "b2f3a4c5-6d7e-8f9a-0b1c-2d3e4f5a6b7c",
      "name": "If Retry Success?"
    },
    {
      "parameters": {
        "jsCode": "// Prepare Archive Record for All-Time Logs\nconst item = $json;\nconst errorTimestamp = new Date(item.timestamp);\nconst resolvedTimestamp = new Date(item.last_retry_at);\nconst timeDiffMs = resolvedTimestamp - errorTimestamp;\nconst timeToResolutionHours = Math.round((timeDiffMs / (1000 * 60 * 60)) * 100) / 100;\n\nreturn [{\n  json: {\n    archived_at: new Date().toISOString(),\n    timestamp: item.timestamp,\n    workflow_id: item.workflow_id,\n    workflow_name: item.workflow_name,\n    execution_id: item.execution_id,\n    failed_node: item.failed_node,\n    error_type: item.error_type,\n    error_message: item.error_message,\n    severity: item.severity,\n    retry_count: item.retry_count,\n    new_execution_id: item.new_execution_id,\n    resolved_at: item.last_retry_at,\n    time_to_resolution_hours: timeToResolutionHours,\n    retry_params: item.retry_params,\n    // Row index for reliable delete (assigned at fetch time)\n    _rowIndex: item._rowIndex\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        11248,
        1776
      ],
      "id": "e5f6a7b8-9c0d-1e2f-3a4b-5c6d7e8f9a0b",
      "name": "Prepare Archive Record"
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "1EuwgFyv-WnXmlDslGT6OhxVGl3qNV5-jQCYQLFx6CC8",
          "mode": "list",
          "cachedResultName": "\ud83d\udea9All-Time Logs",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1EuwgFyv-WnXmlDslGT6OhxVGl3qNV5-jQCYQLFx6CC8/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Sheet1",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1EuwgFyv-WnXmlDslGT6OhxVGl3qNV5-jQCYQLFx6CC8/edit#gid=0"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {}
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "position": [
        11456,
        1776
      ],
      "id": "f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f9a0b1c",
      "name": "Append to All-Time Logs",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "delete",
        "documentId": {
          "__rl": true,
          "value": "YOUR_FAILEDITEMS_SHEET_ID",
          "mode": "list",
          "cachedResultName": "\ud83d\udea98-hour Retries",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "FailedItems",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit#gid=0"
        },
        "options": {
          "startRowNumber": "={{ $('Prepare Archive Record').first().json._rowIndex }}"
        }
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "position": [
        11664,
        1776
      ],
      "id": "a7b8c9d0-1e2f-3a4b-5c6d-7e8f9a0b1c2d",
      "name": "Delete from FailedItems",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": {
          "__rl": true,
          "value": "YOUR_FAILEDITEMS_SHEET_ID",
          "mode": "list",
          "cachedResultName": "\ud83d\udea98-hour Retries",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "FailedItems",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit#gid=0"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "execution_id": "={{ $json.execution_id }}",
            "retry_count": "={{ $json.retry_count }}",
            "status": "=pending_retry"
          },
          "matchingColumns": [
            "execution_id"
          ],
          "schema": [
            {
              "id": "execution_id",
              "displayName": "execution_id",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "retry_count",
              "displayName": "retry_count",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "position": [
        11040,
        2112
      ],
      "id": "acdde3e9-2b00-487e-b766-0789058ef8cf",
      "name": "Update Retry Count",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Mark as escalated - requires human intervention\nconst item = $json;\n\nreturn [{\n  json: {\n    ...item,\n    status: 'escalated',\n    escalated_at: new Date().toISOString()\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        9392,
        2032
      ],
      "id": "4e5238b8-31d9-4e34-b985-231002f0faf3",
      "name": "Mark Escalated"
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": {
          "__rl": true,
          "value": "YOUR_FAILEDITEMS_SHEET_ID",
          "mode": "list",
          "cachedResultName": "\ud83d\udea98-hour Retries",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "FailedItems",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit#gid=0"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "status": "={{ $json.status }}"
          },
          "matchingColumns": [
            "execution_id"
          ],
          "schema": [
            {
              "id": "execution_id",
              "displayName": "execution_id",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "position": [
        9632,
        2032
      ],
      "id": "38d80c96-f267-4c20-8b6a-8ae3c13926f7",
      "name": "Update Status Escalated",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "YOUR_CHAT_ID_1",
        "text": "=\ud83d\udea8 ESCALATION: 3 retries exhausted\n\nWorkflow: {{ $json.workflow_name }}\nNode: {{ $json.failed_node }}\nError: {{ $json.error_message }}\n\nExecution ID: {{ $json.execution_id }}\nError Type: {{ $json.error_type }}\n\n\u26a0\ufe0f Manual intervention required",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        9872,
        2032
      ],
      "id": "d1a7a098-f9b0-49a6-836f-f51f1f72ef03",
      "name": "Alert: Escalation",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "## 8-hour Task Resolver\n\n**Purpose:** Auto-retry failed workflow executions logged in FailedItems sheet.\n\n**Flow:**\n1. Every 8 hours, read pending retryable items\n2. For each item with retry_count < 3:\n   - Call n8n API retry endpoint\n   - Poll execution status every 10s (up to 5 min)\n   - If success \u2192 archive to All-Time Logs\n   - If failed \u2192 update retry_count, keep in queue\n3. For items with retry_count >= 3:\n   - Mark as 'escalated'\n   - Send Telegram alert for human intervention\n\n**Key Fix:** Robust polling loop handles fast and slow workflows",
        "height": 420,
        "width": 360
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        8192,
        1456
      ],
      "id": "0a7ce17e-e228-41f3-bf24-6dbec6edba42",
      "name": "Overview"
    },
    {
      "parameters": {
        "content": "### Retry Path\nretry_count < 3\n\u2192 Calculate Delay (based on Groq calls)\n\u2192 Wait (dynamic, 60-187s)\n\u2192 Execute Retry via API\n\u2192 Extract ID (initialize polling state)\n\u2192 Polling Loop (see Polling Note)",
        "height": 208,
        "width": 424
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        8896,
        1616
      ],
      "id": "999910c9-e401-4db0-a249-ff69d10ad1ac",
      "name": "Retry Note1"
    },
    {
      "parameters": {
        "content": "### Escalation Path\nretry_count >= 3\n\u2192 Human intervention required",
        "height": 152,
        "width": 424
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        8912,
        2032
      ],
      "id": "fd62c1a1-9971-46a6-a31d-dd97a201e66b",
      "name": "Escalation Note"
    },
    {
      "parameters": {
        "content": "### Robust Polling Loop (10s intervals)\n\n**Flow:**\n```\nExtract ID \u2192 Poll Execution Status \u2192 Evaluate Poll\n               \u2191                          \u2193\n          Wait 10s  \u2190\u2190\u2190  Should Continue Polling?\n                              \u2193 (FALSE)\n                         Evaluate Result \u2192 If Retry Success?\n```\n\n**Why polling loop?**\n- Fast executions: exits immediately when done\n- Slow executions: waits up to 5 min (30 polls \u00d7 10s)\n- Old 30s fixed wait was fragile\n\n**Nodes:**\n1. **Extract ID**: Get exec ID, init poll_count=0, is_done=false\n2. **Poll Execution Status**: HTTP GET (uses httpHeaderAuth)\n3. **Evaluate Poll**: Check if done, increment counter\n4. **Should Continue Polling?**: !is_done && poll_count < 30\n5. **Wait 10s**: Loop delay (TRUE branch loops back)\n6. **Evaluate Result**: Final status for routing",
        "height": 424,
        "width": 400
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        10000,
        1360
      ],
      "id": "b8c9d0e1-2f3a-4b5c-6d7e-8f9a0b1c2d3e",
      "name": "Polling Note"
    }
  ],
  "connections": {
    "Every 8 Hours": {
      "main": [
        [
          {
            "node": "Read FailedItems",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read FailedItems": {
      "main": [
        [
          {
            "node": "Prepare Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Items": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "retry_count < 3?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "retry_count < 3?": {
      "main": [
        [
          {
            "node": "Calculate Retry Delay",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark Escalated",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Retry Delay": {
      "main": [
        [
          {
            "node": "Wait Before Retry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait Before Retry": {
      "main": [
        [
          {
            "node": "Execute Retry via API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Retry via API": {
      "main": [
        [
          {
            "node": "Extract ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract ID": {
      "main": [
        [
          {
            "node": "Poll Execution Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll Execution Status": {
      "main": [
        [
          {
            "node": "Evaluate Poll",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Evaluate Poll": {
      "main": [
        [
          {
            "node": "Should Continue Polling?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Should Continue Polling?": {
      "main": [
        [
          {
            "node": "Wait 10s",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Evaluate Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 10s": {
      "main": [
        [
          {
            "node": "Poll Execution Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Evaluate Result": {
      "main": [
        [
          {
            "node": "If Retry Success?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Retry Success?": {
      "main": [
        [
          {
            "node": "Prepare Archive Record",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Retry Count",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Archive Record": {
      "main": [
        [
          {
            "node": "Append to All-Time Logs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append to All-Time Logs": {
      "main": [
        [
          {
            "node": "Delete from FailedItems",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete from FailedItems": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Retry Count": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Escalated": {
      "main": [
        [
          {
            "node": "Update Status Escalated",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Status Escalated": {
      "main": [
        [
          {
            "node": "Alert: Escalation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Alert: Escalation": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}