AutomationFlowsAI & RAG › Nhs Westshire Icb — Foi Web Form Processing

Nhs Westshire Icb — Foi Web Form Processing

NHS Westshire ICB — FOI Web Form Processing. Uses formTrigger, httpRequest, n8n-nodes-resend, googleSheets. Event-driven trigger; 7 nodes.

Event trigger★★★★☆ complexity7 nodesForm TriggerHTTP RequestN8N Nodes ResendGoogle Sheets
AI & RAG Trigger: Event Nodes: 7 Complexity: ★★★★☆ Added:

This workflow follows the Form Trigger → Google Sheets 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 →

Download .json
{
  "name": "NHS Westshire ICB \u2014 FOI Web Form Processing",
  "nodes": [
    {
      "parameters": {
        "formTitle": "Freedom of Information Request \u2014 NHS Westshire ICB",
        "formDescription": "Use this form to submit a Freedom of Information (FOI) request to NHS Westshire ICB. You have a legal right to request recorded information held by the ICB under the Freedom of Information Act 2000. We will respond within 20 working days.",
        "responseMode": "onReceived",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Full Name",
              "fieldType": "text",
              "requiredField": true,
              "fieldId": "full_name",
              "placeholder": "Your full name"
            },
            {
              "fieldLabel": "Email Address",
              "fieldType": "email",
              "requiredField": true,
              "fieldId": "email_address",
              "placeholder": "your.email@example.com"
            },
            {
              "fieldLabel": "Organisation (if applicable)",
              "fieldType": "text",
              "requiredField": false,
              "fieldId": "organisation",
              "placeholder": "Leave blank if making a personal request"
            },
            {
              "fieldLabel": "Your FOI Request",
              "fieldType": "textarea",
              "requiredField": true,
              "fieldId": "request_details",
              "placeholder": "Please describe the information you are requesting in as much detail as possible. The more specific your request, the faster we can respond.",
              "fieldOptions": {
                "values": []
              }
            },
            {
              "fieldLabel": "Preferred Format",
              "fieldType": "dropdown",
              "requiredField": false,
              "fieldId": "preferred_format",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Electronic (email/PDF)"
                  },
                  {
                    "option": "Paper (post)"
                  }
                ]
              }
            },
            {
              "fieldLabel": "Reference to Previous Request (if applicable)",
              "fieldType": "text",
              "requiredField": false,
              "fieldId": "reference_to_previous",
              "placeholder": "e.g. FOI-2025-0042 \u2014 leave blank if this is a new request"
            }
          ]
        },
        "options": {
          "buttonLabel": "Submit FOI Request",
          "respondWithOptions": {
            "values": {
              "respondWith": "text",
              "responseText": "Thank you for submitting your Freedom of Information request to NHS Westshire ICB. We will acknowledge your request by email within 2 hours and respond within 20 working days (as required by the Freedom of Information Act 2000). Your case reference will be included in your acknowledgement email."
            }
          }
        }
      },
      "id": "d6e7f8a9-b0c1-2345-defa-456789012345",
      "name": "N8N Form Trigger",
      "type": "n8n-nodes-base.formTrigger",
      "typeVersion": 2.2,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "language": "javaScript",
        "jsCode": "// Format the form submission as a standard FOI request\nconst form = $input.item.json;\n\n// Generate case reference\nconst year = new Date().getFullYear();\nconst randomNum = Math.floor(Math.random() * 9000) + 1000;\nconst caseRef = `FOI-${year}-${randomNum}`;\n\n// Get submission date\nconst receivedDate = new Date();\nconst receivedDateStr = receivedDate.toLocaleDateString('en-GB', {\n  weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'\n});\n\n// Calculate 20-working-day deadline\nfunction addWorkingDays(startDate, days) {\n  let count = 0;\n  let current = new Date(startDate);\n  const bankHolidays = [\n    '2025-12-25', '2025-12-26', '2026-01-01', '2026-04-03', '2026-04-06',\n    '2026-05-04', '2026-05-25', '2026-08-31', '2026-12-25', '2026-12-28'\n  ];\n  while (count < days) {\n    current.setDate(current.getDate() + 1);\n    const dayOfWeek = current.getDay();\n    const dateStr = current.toISOString().split('T')[0];\n    if (dayOfWeek !== 0 && dayOfWeek !== 6 && !bankHolidays.includes(dateStr)) {\n      count++;\n    }\n  }\n  return current;\n}\n\nconst deadlineDate = addWorkingDays(receivedDate, 20);\nconst deadlineDateStr = deadlineDate.toLocaleDateString('en-GB', {\n  weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'\n});\n\n// Extract form fields\nconst senderName = form.full_name || form['Full Name'] || 'Unknown';\nconst senderEmail = form.email_address || form['Email Address'] || '';\nconst organisation = form.organisation || form['Organisation (if applicable)'] || '';\nconst requestDetails = form.request_details || form['Your FOI Request'] || '';\nconst preferredFormat = form.preferred_format || form['Preferred Format'] || 'Electronic (email/PDF)';\nconst previousRef = form.reference_to_previous || form['Reference to Previous Request (if applicable)'] || '';\n\n// Format as standard email-style body for consistent processing\nconst formattedBody = `FOI REQUEST SUBMITTED VIA WEB FORM\n\nSubmitted by: ${senderName}${organisation ? ' (' + organisation + ')' : ''}\nEmail: ${senderEmail}\nPreferred format: ${preferredFormat}\n${previousRef ? 'Reference to previous request: ' + previousRef : ''}\n\nREQUEST:\n${requestDetails}`;\n\nreturn [{\n  json: {\n    caseRef,\n    senderEmail,\n    senderName,\n    organisation,\n    subject: `FOI Request (Web Form) \u2014 ${requestDetails.substring(0, 80)}${requestDetails.length > 80 ? '...' : ''}`,\n    body: formattedBody,\n    requestDetails,\n    preferredFormat,\n    previousRef,\n    receivedDate: receivedDate.toISOString(),\n    receivedDateStr,\n    deadlineDate: deadlineDate.toISOString(),\n    deadlineDateStr,\n    source: 'WEB_FORM'\n  }\n}];"
      },
      "id": "e7f8a9b0-c1d2-3456-efab-567890123456",
      "name": "Code: Format as FOI Request",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        440,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "anthropic-beta",
              "value": "prompt-caching-2024-07-31"
            }
          ]
        },
        "sendBody": true,
        "contentType": "json",
        "body": "={{\n  JSON.stringify({\n    model: 'claude-sonnet-4-6',\n    max_tokens: 4000,\n    system: [\n      {\n        type: 'text',\n        text: 'You are the Freedom of Information & EIR Agent for NHS Westshire ICB (NHS Westshire Integrated Care Board, Westshire House, 12 Cathedral Quarter, Westminster-upon-Avon WS1 2AB). Process the incoming FOI web form request and produce a JSON response with: request_type (FOI/EIR/SAR/GENERAL/UNCLEAR), classification_confidence, summary, subject_matter, potential_exemptions (array), escalation_required (boolean), escalation_reason, requester_type, likely_held_by_icb, disclosure_decision (DISCLOSE/PARTIAL/REFUSE/NOT_HELD/REFER/TRANSFER), information_held, exemptions_applied (array of objects with section/description/type/public_interest_argument), draft_acknowledgement (full email text including case reference ' + $json.caseRef + ' and deadline ' + $json.deadlineDateStr + '), draft_response (full draft response letter for FOI Lead review), internal_notes. Respond ONLY with valid JSON.',\n        cache_control: { type: 'ephemeral' }\n      }\n    ],\n    messages: [\n      {\n        role: 'user',\n        content: 'FOI WEB FORM SUBMISSION\\n\\nCase Reference: ' + $json.caseRef + '\\nDate: ' + $json.receivedDateStr + '\\nDeadline: ' + $json.deadlineDateStr + '\\nName: ' + $json.senderName + '\\nEmail: ' + $json.senderEmail + (($json.organisation) ? '\\nOrganisation: ' + $json.organisation : '') + '\\nPreferred format: ' + $json.preferredFormat + '\\n\\nRequest:\\n' + $json.requestDetails\n      }\n    ]\n  })\n}}",
        "options": {
          "timeout": 60000,
          "response": {
            "response": {
              "fullResponse": false,
              "responseFormat": "json"
            }
          }
        }
      },
      "id": "f8a9b0c1-d2e3-4567-fabc-678901234567",
      "name": "HTTP Request: Claude API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        640,
        300
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "language": "javaScript",
        "jsCode": "// Parse the Claude API response for form submissions\nconst response = $input.item.json;\nconst prevData = $('Code: Format as FOI Request').item.json;\n\nlet responseText = '';\nif (response.content && response.content[0] && response.content[0].text) {\n  responseText = response.content[0].text;\n} else {\n  throw new Error('Unexpected API response: ' + JSON.stringify(response));\n}\n\nlet analysis;\ntry {\n  const jsonMatch = responseText.match(/```json\\s*([\\s\\S]*?)\\s*```/) ||\n                    responseText.match(/```\\s*([\\s\\S]*?)\\s*```/);\n  const jsonStr = jsonMatch ? jsonMatch[1] : responseText;\n  analysis = JSON.parse(jsonStr.trim());\n} catch (e) {\n  // Fallback acknowledgement\n  const fallbackAck = `Dear ${prevData.senderName},\n\nThank you for your Freedom of Information request submitted via our online form.\n\nWe have registered your request with case reference ${prevData.caseRef}.\n\nWe will respond within 20 working days, by ${prevData.deadlineDateStr}.\n\nIf you have any queries, please contact us at foi@westshire.icb.nhs.uk quoting your case reference.\n\nFreedom of Information Team\nNHS Westshire Integrated Care Board\nWestshire House, 12 Cathedral Quarter, Westminster-upon-Avon WS1 2AB\nfoi@westshire.icb.nhs.uk`;\n\n  analysis = {\n    request_type: 'UNCLEAR',\n    disclosure_decision: 'PENDING_MANUAL_REVIEW',\n    draft_acknowledgement: fallbackAck,\n    draft_response: 'MANUAL REVIEW REQUIRED.',\n    internal_notes: `Form submission parsing failed. Raw: ${responseText.substring(0, 500)}`,\n    escalation_required: true,\n    potential_exemptions: []\n  };\n}\n\nreturn [{\n  json: {\n    ...prevData,\n    analysis,\n    claudeUsage: response.usage || {}\n  }\n}];"
      },
      "id": "a9b0c1d2-e3f4-5678-abcd-789012345678",
      "name": "Code: Parse Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        840,
        300
      ]
    },
    {
      "parameters": {
        "from": "={{ $env.FOI_EMAIL_ADDRESS }}",
        "to": "={{ $json.senderEmail }}",
        "subject": "Your FOI request \u2014 Case Reference {{ $json.caseRef }} \u2014 NHS Westshire ICB",
        "emailType": "text",
        "message": "={{ $json.analysis.draft_acknowledgement }}",
        "options": {
          "replyTo": "foi@westshire.icb.nhs.uk"
        }
      },
      "id": "b0c1d2e3-f4a5-6789-bcde-890123456789",
      "name": "Send Confirmation to Requester",
      "type": "n8n-nodes-resend.resend",
      "typeVersion": 1,
      "position": [
        1040,
        300
      ],
      "credentials": {
        "resendApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "from": "={{ $env.FOI_EMAIL_ADDRESS }}",
        "to": "={{ $env.FOI_REVIEWER_EMAIL }}",
        "subject": "[FOI FORM SUBMISSION] {{ $json.caseRef }} \u2014 {{ $json.analysis.request_type || 'UNKNOWN' }}: {{ $json.analysis.subject_matter || $json.subject }} \u2014 Deadline: {{ $json.deadlineDateStr }}",
        "emailType": "text",
        "message": "=FOI WEB FORM SUBMISSION \u2014 NHS WESTSHIRE ICB\n============================================\n\nCase Reference: {{ $json.caseRef }}\nSource: WEB FORM\nDate Received: {{ $json.receivedDateStr }}\nStatutory Deadline: {{ $json.deadlineDateStr }}\nRequest Type: {{ $json.analysis.request_type || 'UNCLEAR' }}\nDisclosure Decision (Draft): {{ $json.analysis.disclosure_decision || 'PENDING' }}\n\nREQUESTER:\nName: {{ $json.senderName }}\nEmail: {{ $json.senderEmail }}\n{{ $json.organisation ? 'Organisation: ' + $json.organisation : '' }}\nPreferred format: {{ $json.preferredFormat }}\n\nREQUEST DETAILS:\n{{ $json.requestDetails }}\n\nCLASSIFICATION:\n{{ $json.analysis.summary || $json.analysis.request_type }}\n\nESCALATION REQUIRED: {{ $json.analysis.escalation_required ? 'YES' : 'NO' }}\n{{ $json.analysis.escalation_reason ? 'REASON: ' + $json.analysis.escalation_reason : '' }}\n\nINTERNAL NOTES:\n{{ $json.analysis.internal_notes }}\n\n--------------------------------------------\nDRAFT RESPONSE (FOR YOUR REVIEW AND APPROVAL):\n--------------------------------------------\n{{ $json.analysis.draft_response }}\n\n============================================\nConfirmation email has been sent to requester.\n============================================",
        "options": {
          "replyTo": "foi@westshire.icb.nhs.uk"
        }
      },
      "id": "c1d2e3f4-a5b6-7890-cdef-901234567890",
      "name": "Send to Reviewer",
      "type": "n8n-nodes-resend.resend",
      "typeVersion": 1,
      "position": [
        1240,
        300
      ],
      "credentials": {
        "resendApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "={{ $env.GOOGLE_SHEETS_ID }}",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "FOI Case Register",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Case Reference": "={{ $json.caseRef }}",
            "Date Received": "={{ $json.receivedDateStr }}",
            "Requester Name": "={{ $json.senderName }}",
            "Requester Email": "={{ $json.senderEmail }}",
            "Organisation": "={{ $json.organisation }}",
            "Subject": "={{ $json.subject }}",
            "Request Type": "={{ $json.analysis.request_type || 'UNCLEAR' }}",
            "Subject Matter": "={{ $json.analysis.subject_matter || '' }}",
            "Deadline": "={{ $json.deadlineDateStr }}",
            "Draft Decision": "={{ $json.analysis.disclosure_decision || 'PENDING' }}",
            "Escalation Required": "={{ $json.analysis.escalation_required ? 'YES' : 'NO' }}",
            "Status": "PENDING_REVIEW",
            "Source": "WEB_FORM",
            "Logged At": "={{ new Date().toLocaleDateString('en-GB') }}"
          },
          "matchingColumns": [],
          "schema": []
        },
        "options": {
          "valueInputMode": "USER_ENTERED"
        }
      },
      "id": "d2e3f4a5-b6c7-8901-defa-012345678901",
      "name": "Google Sheets: Log Case",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.4,
      "position": [
        1440,
        300
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "N8N Form Trigger": {
      "main": [
        [
          {
            "node": "Code: Format as FOI Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: Format as FOI Request": {
      "main": [
        [
          {
            "node": "HTTP Request: Claude API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request: Claude API": {
      "main": [
        [
          {
            "node": "Code: Parse Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: Parse Response": {
      "main": [
        [
          {
            "node": "Send Confirmation to Requester",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Confirmation to Requester": {
      "main": [
        [
          {
            "node": "Send to Reviewer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send to Reviewer": {
      "main": [
        [
          {
            "node": "Google Sheets: Log Case",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner",
    "timezone": "Europe/London"
  },
  "versionId": "1.0.0",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "id": "foi-form-workflow-001",
  "tags": [
    {
      "createdAt": "2026-05-14T09:00:00.000Z",
      "updatedAt": "2026-05-14T09:00:00.000Z",
      "id": "tag-foi",
      "name": "FOI"
    },
    {
      "createdAt": "2026-05-14T09:00:00.000Z",
      "updatedAt": "2026-05-14T09:00:00.000Z",
      "id": "tag-nhs",
      "name": "NHS"
    }
  ]
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

NHS Westshire ICB — FOI Web Form Processing. Uses formTrigger, httpRequest, n8n-nodes-resend, googleSheets. Event-driven trigger; 7 nodes.

Source: https://github.com/pwyman/NHSManagedAgents/blob/c7627178dfefdb8b9692fe4212399b80cf086346/n8n-workflows/foi-form-workflow.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Inquiry-Agent. Uses @digitalocean/n8n-nodes-digitalocean-gradient-serverless-inference, stopAndError, googleDocs, gmail. Event-driven trigger; 59 nodes.

@Digitalocean/N8N Nodes Digitalocean Gradient Serverless Inference, Stop And Error, Google Docs +4
AI & RAG

Who this is for

YouTube, Form Trigger, Google Sheets +2
AI & RAG

🎯 Create viral TikToks, Shorts, Reels, podcasts, and ASMR videos in minutes — all on autopilot.

OpenAI, HTTP Request, Form Trigger +7
AI & RAG

Episode 11: AI shorts factory app. Uses httpRequest, googleSheets, lmChatOpenAi, lmChatOllama. Event-driven trigger; 96 nodes.

HTTP Request, Google Sheets, OpenAI Chat +15
AI & RAG

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Form Trigger, Google Sheets, HTTP Request +3