AutomationFlowsWeb Scraping › Send Indian Tender Email Reports From Tendersinfo.net Results

Send Indian Tender Email Reports From Tendersinfo.net Results

ByRahul Joshi @rahul08 on n8n.io

This workflow fetches live tenders from TendersInfo.net based on user-provided keywords, filters for GEM (Government e-Marketplace) and MSE (Micro & Small Enterprises) eligible opportunities, and generates a professional HTML email report grouped by company. The webhook receives…

Webhook trigger★★★★☆ complexity13 nodesHTTP Request
Web Scraping Trigger: Webhook Nodes: 13 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #15886 — we link there as the canonical source.

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
{
  "id": "zAUNmHPItpviDVoV",
  "name": "Tender result on frontend",
  "tags": [],
  "nodes": [
    {
      "id": "d2fbcba5-ad52-49d1-9534-c92bfaad8383",
      "name": "Overview Sticky",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        320
      ],
      "parameters": {
        "width": 406,
        "height": 577,
        "content": "## \ud83c\udfaf Indian Tender Search & Email Report\n\n### How it works\nThis workflow fetches live tenders from TendersInfo.net based on user-provided keywords, filters for GEM (Government e-Marketplace) and MSE (Micro & Small Enterprises) eligible opportunities, and generates a professional HTML email report grouped by company. The webhook receives search criteria, queries the tender API, parses responses, filters relevant tenders, and formats results into a readable table.\n\n### Setup steps\n1. **Replace API authentication**: Update the `Cookie` header in \"Fetch Tender Data from API\" node with your valid `ANTI_FORGERY_TOKEN` and `SESSION_ID` from TendersInfo.net\n2. **Configure webhook**: Copy the production webhook URL from the \"Webhook Trigger\" node\n3. **Test with sample data**: Send a POST request with `{\"keywords\": \"software\", \"msme\": \"eligible\", \"email\": \"user@example.com\"}` to verify the flow\n4. **Activate workflow**: Enable the workflow to start processing real tender searches"
      },
      "typeVersion": 1
    },
    {
      "id": "bbb26d0c-d3b7-4ee3-85c1-9d3833cc5f45",
      "name": "Webhook Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        272
      ],
      "parameters": {
        "color": 2,
        "content": "## \ud83d\udce5 Webhook Entry\nReceives POST requests with search parameters including keywords, MSME preferences, and recipient email address."
      },
      "typeVersion": 1
    },
    {
      "id": "42c2b9b5-654d-466a-959d-6a08cd3ab1e5",
      "name": "API Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        288
      ],
      "parameters": {
        "color": 2,
        "width": 360,
        "height": 132,
        "content": "## \ud83d\udd0d API Fetch & Parse\nQueries TendersInfo.net API with user keywords and extracts all tender listings from the JSON response into structured individual records."
      },
      "typeVersion": 1
    },
    {
      "id": "4f2c0770-4536-4369-801c-114865c3be88",
      "name": "Filter Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        288
      ],
      "parameters": {
        "color": 2,
        "width": 360,
        "height": 132,
        "content": "## \u2705 Filter & Format\nKeeps only GEM and MSE-eligible tenders, then maps fields for email presentation including links, dates, and company details."
      },
      "typeVersion": 1
    },
    {
      "id": "192b7f46-c130-4f25-8107-4bf2ee1e450b",
      "name": "Output Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        272
      ],
      "parameters": {
        "color": 2,
        "width": 340,
        "height": 148,
        "content": "## \ud83d\udcca HTML Generation & Response\nBuilds a styled HTML table grouped by company name and returns it as the webhook response for email delivery or display."
      },
      "typeVersion": 1
    },
    {
      "id": "39341326-4c08-440c-9134-938aebd23644",
      "name": "Security Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -288,
        144
      ],
      "parameters": {
        "color": 3,
        "width": 320,
        "height": 140,
        "content": "## \ud83d\udd10 Credentials & Security\nReplace `__REPLACE__` tokens in the Cookie header with valid session credentials from TendersInfo.net. Never share personal session IDs or API keys publicly."
      },
      "typeVersion": 1
    },
    {
      "id": "661c29a8-c3ad-44bf-a878-a33ee6099232",
      "name": "Webhook Trigger1",
      "type": "n8n-nodes-base.webhook",
      "position": [
        176,
        464
      ],
      "parameters": {
        "path": "ec731146-5297-410c-bfc4-f6fbe59a8f3f",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "bfe068d0-b93a-43f0-a614-50fa6cc459f0",
      "name": "Parse Tender Response1",
      "type": "n8n-nodes-base.code",
      "position": [
        624,
        464
      ],
      "parameters": {
        "jsCode": "// Get the input data\nconst inputData = $input.all();\n\n// Initialize array to store all tenders\nlet allTenders = [];\n\n// Loop through each input item\nfor (const item of inputData) {\n  // Parse the JSON string if it's a string, otherwise use directly\n  let parsedData;\n  \n  if (typeof item.json.data === 'string') {\n    parsedData = JSON.parse(item.json.data);\n  } else {\n    parsedData = item.json.data || item.json;\n  }\n  \n  // Extract TenderList\n  if (parsedData.TenderList && Array.isArray(parsedData.TenderList)) {\n    allTenders = allTenders.concat(parsedData.TenderList);\n  }\n}\n\n// Format each tender as a separate output item\nconst formattedOutput = allTenders.map(tender => ({\n  json: {\n    tenderRefNo: tender.tenderrefno,\n    tcNo: tender.tcno,\n    tenderProcId: tender.tenderprocid,\n    country: tender.countryname,\n    state: tender.statename,\n    city: tender.cityname,\n    keyword: tender.keywordname,\n    subIndustry: tender.subindustryname,\n    earnestMoney: tender.earnestmoney,\n    address: tender.address,\n    quantity: tender.quantity,\n    tenderBrief: tender.tendersbriefnew || tender.tendersbrief,\n    companyName: tender.companyname,\n    tenderDate: tender.tenderdate,\n    openingDate: tender.openingdate,\n    closingDate: tender.closingdate,\n    tenderValue: tender.tendervalue,\n    currency: tender.currcode,\n    isGEM: tender.isgem,\n    isPQ: tender.ispq,\n    isBOQ: tender.isboq,\n    isDocument: tender.isdocument,\n    isFreeTender: tender.isfreetender,\n    isMSE: tender.ismse,\n    isCorrigendum: tender.iscorrigendum,\n    biddingType: tender.biddingtype,\n    publicationDate: tender.publicationdate,\n    fundAgency: tender.fundagencyname,\n    docFees: tender.docfees,\n    descriptionLink: tender.descriptionlink,\n    originalSource: tender.originalsource,\n    scorePercentage: tender.scorePercentage,\n    elasticScore: tender.elastic_score\n  }\n}));\n\nreturn formattedOutput;"
      },
      "typeVersion": 2
    },
    {
      "id": "1850abac-3bbe-4424-a78a-3ed4fd2901af",
      "name": "Select Email Fields1",
      "type": "n8n-nodes-base.set",
      "position": [
        1072,
        464
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "96e09add-c473-4795-949f-0e8e87c7b764",
              "name": "=Name",
              "type": "string",
              "value": "={{ $json.companyName }}"
            },
            {
              "id": "02a76031-a5a3-4075-aacd-97f79b539e8e",
              "name": "Description Link",
              "type": "string",
              "value": "={{ $json.descriptionLink }}"
            },
            {
              "id": "8a6b0b2d-e689-41cb-9f2b-cad8c179d01d",
              "name": "TenderRefNo",
              "type": "string",
              "value": "={{ $json.tenderRefNo }}"
            },
            {
              "id": "b6e779fb-2464-48f6-9160-0ad77c6d13f1",
              "name": "TcNo",
              "type": "string",
              "value": "={{ $json.tcNo }}"
            },
            {
              "id": "9b59a6da-4b6d-4a65-b094-e7b12cbfb57b",
              "name": "TenderProcId",
              "type": "string",
              "value": "={{ $json.tenderProcId }}"
            },
            {
              "id": "afc1819d-2a84-47b1-a3e3-46bbc85c2061",
              "name": "Country",
              "type": "string",
              "value": "={{ $json.country }}"
            },
            {
              "id": "d8d658ba-59db-4276-9aa2-4d4a9520a079",
              "name": "State",
              "type": "string",
              "value": "= {{$json.state }}"
            },
            {
              "id": "420cfa86-e752-4a7f-8a74-ce806fd29eca",
              "name": "City",
              "type": "string",
              "value": "={{ $json.city }}"
            },
            {
              "id": "479b39bf-b616-4c76-ad68-7286e2ee6df9",
              "name": "TenderBrief",
              "type": "string",
              "value": "={{ $json.tenderBrief }}"
            },
            {
              "id": "9f39f749-1cc8-4ebe-bac1-c1bb8175c86c",
              "name": "Company Name",
              "type": "string",
              "value": "={{ $json.companyName }}"
            },
            {
              "id": "d25bac11-4278-48c7-a4d7-4821af82bfca",
              "name": "Tender Date",
              "type": "string",
              "value": "={{ $json.tenderDate }}"
            },
            {
              "id": "10c45fcd-2da8-4050-b3eb-119ed216cbd0",
              "name": "Opening Date",
              "type": "string",
              "value": "={{ $json.openingDate }}"
            },
            {
              "id": "854b9608-f6d9-447d-8545-cd237374c5bf",
              "name": "Closing Date",
              "type": "string",
              "value": "={{ $json.closingDate }}"
            },
            {
              "id": "a2a7bf56-e720-44f9-b1e6-740e2d1672de",
              "name": "Original_Source",
              "type": "string",
              "value": "={{ $json.originalSource }}"
            },
            {
              "id": "ad528850-f5aa-436a-bb05-2dd9a169b8f2",
              "name": "Responder email",
              "type": "string",
              "value": "={{ $('Webhook Trigger1').item.json.body.email }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "3c071e78-a5a5-4698-b1cd-99cc00e71073",
      "name": "Fetch Tender Data from API1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        400,
        464
      ],
      "parameters": {
        "url": "https://tendersinfo.net/TenderAI/GetTendersList",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "form-urlencoded",
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "searchkeyword",
              "value": "={{ $json.body.keywords }} tenders from {{ $json.body.location }} {{ $json.body.msme }}"
            },
            {
              "name": "tabindex",
              "value": "1"
            },
            {
              "name": "maintabindex",
              "value": "0"
            },
            {
              "name": "total",
              "value": "200"
            },
            {
              "name": "tender_typewise",
              "value": "live"
            },
            {
              "name": "rescount",
              "value": "0"
            },
            {
              "name": "categoryflag",
              "value": "1"
            },
            {
              "name": "last_rescount",
              "value": "20"
            },
            {
              "name": "sortingScore",
              "value": "0"
            },
            {
              "name": "gemtender",
              "value": "1"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "*/*"
            },
            {
              "name": "Origin",
              "value": "https://tendersinfo.net"
            },
            {
              "name": "Referer",
              "value": "https://tendersinfo.net/TenderAI/TenderAIList"
            },
            {
              "name": "X-Requested-With",
              "value": "XMLHttpRequest"
            },
            {
              "name": "User-Agent",
              "value": "Mozilla/5.0"
            },
            {
              "name": "Cookie",
              "value": "ANTI_FORGERY_TOKEN=__REPLACE__; SESSION_ID=__REPLACE__; TenderTypewise=live;"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "6203e9be-f85e-49be-8cae-0d5f7bcfb004",
      "name": "Filter GEM Tenders Only1",
      "type": "n8n-nodes-base.filter",
      "position": [
        848,
        464
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "6e683df5-0eca-4fa8-8459-1abbd816a790",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.isGEM }}",
              "rightValue": "1"
            },
            {
              "id": "70c84182-508f-4ba4-96fc-5f9a1e0a2be4",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.isMSE }}",
              "rightValue": "=1"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a2899512-ed5b-4da3-9d6b-37e26503303b",
      "name": "Respond to Webhook1",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1520,
        464
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "={{$node['Build HTML Table'].json['html']}}\n"
      },
      "typeVersion": 1.4
    },
    {
      "id": "6e3b9ca1-d8ac-4711-909d-8fbb27334249",
      "name": "Build HTML Table",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        464
      ],
      "parameters": {
        "jsCode": "const items = $input.all().map(i => i.json);\n\n// ---------- Helpers ----------\nfunction toTitleCase(str) {\n  if (!str) return \"Unknown Department\";\n  return str\n    .toLowerCase()\n    .replace(/\\s+/g, \" \")\n    .trim()\n    .split(\" \")\n    .map(w => w.charAt(0).toUpperCase() + w.slice(1))\n    .join(\" \");\n}\n\n// ---------- Group by Department ----------\nconst grouped = {};\n\nitems.forEach(t => {\n  const rawDept = t[\"Company Name\"] || t.Name || \"Unknown Department\";\n  const deptTitle = toTitleCase(rawDept);\n\n  if (!grouped[deptTitle]) grouped[deptTitle] = [];\n  grouped[deptTitle].push(t);\n});\n\n// ---------- CSS ----------\nlet html = `\n<style>\nbody {\n  font-family: Inter, Arial, sans-serif;\n  background: #f6f8fb;\n}\n.tender-wrapper {\n  max-width: 1100px;\n  margin: auto;\n}\n.department {\n  margin: 30px 0 15px;\n  padding: 14px 18px;\n  background: linear-gradient(135deg, #1e3c72, #2a5298);\n  color: #fff;\n  border-radius: 10px;\n  font-size: 20px;\n  font-weight: 600;\n}\n.tender-card {\n  background: #fff;\n  border-radius: 12px;\n  padding: 18px 20px;\n  margin-bottom: 16px;\n  box-shadow: 0 6px 16px rgba(0,0,0,0.08);\n  border-left: 5px solid #2a5298;\n}\n.tender-grid {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));\n  gap: 10px 20px;\n}\n.tender-item {\n  font-size: 14px;\n}\n.tender-item strong {\n  color: #1e3c72;\n}\n.tender-brief {\n  grid-column: 1 / -1;\n  margin-top: 8px;\n}\n.tender-link {\n  margin-top: 14px;\n  display: inline-block;\n  padding: 8px 14px;\n  background: #2a5298;\n  color: #fff !important;\n  border-radius: 6px;\n  text-decoration: none;\n  font-size: 13px;\n}\n.tender-link:hover {\n  background: #1e3c72;\n}\n.footer-note {\n  margin-top: 40px;\n  text-align: center;\n  font-size: 12px;\n  color: #666;\n}\n</style>\n\n<div class=\"tender-wrapper\">\n`;\n\n// ---------- HTML ----------\nObject.entries(grouped).forEach(([dept, tenders]) => {\n  html += `<div class=\"department\">${dept}</div>`;\n\n  tenders.forEach(t => {\n    html += `\n      <div class=\"tender-card\">\n        <div class=\"tender-grid\">\n          <div class=\"tender-item\"><strong>Tender Ref:</strong> ${t.TenderRefNo || \"-\"}</div>\n          <div class=\"tender-item\"><strong>TC No:</strong> ${t.TcNo || \"-\"}</div>\n          <div class=\"tender-item\"><strong>Proc ID:</strong> ${t.TenderProcId || \"-\"}</div>\n          <div class=\"tender-item\"><strong>Country:</strong> ${toTitleCase(t.Country)}</div>\n          <div class=\"tender-item\"><strong>State:</strong> ${toTitleCase(t.State)}</div>\n          <div class=\"tender-item\"><strong>City:</strong> ${toTitleCase(t.City)}</div>\n          <div class=\"tender-item\"><strong>Tender Date:</strong> ${t[\"Tender Date\"] || \"-\"}</div>\n          <div class=\"tender-item\"><strong>Opening Date:</strong> ${t[\"Opening Date\"] || \"-\"}</div>\n          <div class=\"tender-item\"><strong>Closing Date:</strong> ${t[\"Closing Date\"] || \"-\"}</div>\n\n          <div class=\"tender-brief\">\n            <strong>Brief:</strong><br>\n            ${t.TenderBrief || \"-\"}\n          </div>\n        </div>\n\n        <a class=\"tender-link\" href=\"${t[\"Description Link\"]}\" target=\"_blank\">\n          View Tender Details\n        </a>\n      </div>\n    `;\n  });\n});\n\nhtml += `\n  <div class=\"footer-note\">\n    Source: GeM / TenderTiger \u2022 Generated Automatically\n  </div>\n</div>\n`;\n\n// ---------- Return ----------\nreturn [{ json: { html } }];\n\n"
      },
      "typeVersion": 2
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "67845b2e-27a6-45c3-963d-c0a4efed0e60",
  "connections": {
    "Build HTML Table": {
      "main": [
        [
          {
            "node": "Respond to Webhook1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook Trigger1": {
      "main": [
        [
          {
            "node": "Fetch Tender Data from API1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Email Fields1": {
      "main": [
        [
          {
            "node": "Build HTML Table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Tender Response1": {
      "main": [
        [
          {
            "node": "Filter GEM Tenders Only1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter GEM Tenders Only1": {
      "main": [
        [
          {
            "node": "Select Email Fields1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Tender Data from API1": {
      "main": [
        [
          {
            "node": "Parse Tender Response1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This workflow fetches live tenders from TendersInfo.net based on user-provided keywords, filters for GEM (Government e-Marketplace) and MSE (Micro & Small Enterprises) eligible opportunities, and generates a professional HTML email report grouped by company. The webhook receives…

Source: https://n8n.io/workflows/15886/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

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

Web Scraping

This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di

n8n, Execute Workflow Trigger, HTTP Request +1
Web Scraping

This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .

HTTP Request, Ssh
Web Scraping

eek-Go v2 (Batch-Then-Review). Uses httpRequest. Webhook trigger; 75 nodes.

HTTP Request
Web Scraping

This workflow receives webhook requests from a content calendar and uses the X API v2 to publish text posts, threads, image/video posts, and polls, as well as delete existing posts and run a credentia

HTTP Request
Web Scraping

This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c

HTTP Request