{
  "id": "xTGyTymLhA2_qGvJw1OGz",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "\ud83c\udde6\ud83c\uddf9 Austrian Tender Monitor \u2014 Daily PDF Extraction via TED + Slack Alerts",
  "tags": [],
  "nodes": [
    {
      "id": "60a5a936-cf6d-4b00-9a83-69e770c820fd",
      "name": "Daily 7am Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        2816,
        1520
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 7
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "9cb135be-5083-462b-a1f6-27e05604bfcf",
      "name": "Fetch Austrian Tenders from TED",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3040,
        1520
      ],
      "parameters": {
        "url": "https://api.ted.europa.eu/v3/notices/search",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"query\": \"buyer-country IN (AUT) AND publication-date >= {{ $now.toFormat('yyyyMMdd') }}\",\n  \"fields\": [\n    \"publication-number\",\n    \"publication-date\",\n    \"notice-type\",\n    \"buyer-name\",\n    \"links\"\n  ],\n  \"scope\": \"ACTIVE\",\n  \"limit\": 100,\n  \"page\": 1,\n  \"paginationMode\": \"PAGE_NUMBER\"\n}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.3
    },
    {
      "id": "78afba2d-65b9-4a39-b281-955d97a50a46",
      "name": "Split Notices into Items",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        3248,
        1520
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "notices"
      },
      "typeVersion": 1
    },
    {
      "id": "727f49b7-57bd-480b-ae47-40024828afa2",
      "name": "Filter: Open Tenders Only",
      "type": "n8n-nodes-base.if",
      "position": [
        3472,
        1520
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "9fd456d0-2957-42da-b18f-4ddc96258563",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json['notice-type'] }}",
              "rightValue": "can-standard"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "6e100a7e-549b-43cc-8594-f78b5b567d5e",
      "name": "Loop Over Tenders",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        3696,
        1520
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "2d5e5d39-1d84-445e-9fab-e59541b75ac5",
      "name": "Rate Limit: TED API",
      "type": "n8n-nodes-base.wait",
      "position": [
        3920,
        1520
      ],
      "parameters": {
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "724e6abd-fa81-40fd-a504-a5402bed73cc",
      "name": "Download Tender PDF",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        4128,
        1520
      ],
      "parameters": {
        "url": "={{ $json.links.pdf.DEU }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.3,
      "waitBetweenTries": 2000
    },
    {
      "id": "d46b1f99-4026-449c-a2e6-1ecfe9099883",
      "name": "Rate Limit: easybits API",
      "type": "n8n-nodes-base.wait",
      "position": [
        4352,
        1520
      ],
      "parameters": {
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "f4489334-9c9d-4cca-a263-cd23c3756256",
      "name": "easybits - Extract a document",
      "type": "@easybits/n8n-nodes-extractor.easybitsExtractor",
      "position": [
        4576,
        1520
      ],
      "parameters": {},
      "credentials": {
        "easybitsExtractorApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2,
      "waitBetweenTries": 5000
    },
    {
      "id": "ac65533c-c5f9-4bad-8d38-903f96cb3350",
      "name": "Filter: Min. \u20ac100k Value",
      "type": "n8n-nodes-base.if",
      "position": [
        4800,
        1520
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "1ff0ccd8-a529-4cca-8f1b-692941f870c2",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ Number($json.data.estimated_contract_value) || 0 }}",
              "rightValue": 100000
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "fb9df5cc-fad7-4a49-ac50-cbcca9da8aee",
      "name": "Send Slack Alert",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5008,
        1520
      ],
      "parameters": {
        "url": "https://hooks.slack.com/services/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",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"text\": \"\ud83d\udd14 *Neue Ausschreibung \u2013 \u00d6sterreich*\\n\\n*Titel:* {{ $('easybits - Extract a document').item.json.data.tender_title }}\\n*Auftraggeber:* {{ $('easybits - Extract a document').item.json.data.procuring_entity_name }}\\n*Bundesland:* {{ $('easybits - Extract a document').item.json.data.federal_state }}\\n*Auftragswert:* {{ $('easybits - Extract a document').item.json.data.estimated_contract_value || 'nicht angegeben' }} \u20ac\\n*Frist:* {{ $('easybits - Extract a document').item.json.data.application_deadline || 'nicht angegeben' }}\\n*CPV:* {{ $('easybits - Extract a document').item.json.data.cpv_code }}\\n*Kontakt:* {{ $('easybits - Extract a document').item.json.data.procuring_entity_email }}\\n*PDF:* {{ $('Split Notices into Items').item.json.links.pdf.DEU }}\"\n}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.3
    },
    {
      "id": "71311af1-59a6-403a-a313-0d41120de55c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2176,
        1056
      ],
      "parameters": {
        "width": 604,
        "height": 744,
        "content": "## Tender Monitor\n**Powered by TED Europa \u00b7 easybits.tech \u00b7 Slack**\n\nAutomatically fetches all new Austrian public tenders from TED Europa every morning, extracts structured data from each PDF using easybits.tech AI extraction, and sends a Slack notification for high-value opportunities \u2014 all without manual review.\n\n## How it works\n1. **Daily 7am Trigger** fires the workflow every morning\n2. **Fetch Austrian Tenders from TED** calls the TED v3 API for today's Austrian notices\n3. **Split Notices into Items** splits the response array into individual tender items\n4. **Filter: Open Tenders Only** removes already-awarded contracts (`can-standard`)\n5. **Loop Over Tenders** processes each tender one by one with rate limiting\n6. **Download Tender PDF** fetches the German-language PDF from TED\n7. **easybits - Extract a document** extracts structured fields: title, contracting authority, federal state, contract value, deadline, CPV code, contact email\n8. **Filter: Min. \u20ac100k Value** sends Slack alerts only for contracts \u2265 \u20ac100,000\n9. **Send Slack Alert** posts a formatted message with all key details + PDF link\n\n## Setup\n1. Add your **easybits.tech** API key via the easybits Extractor credential\n2. Replace the Slack Webhook URL in the **Send Slack Alert** node\n3. Adjust the **\u20ac100k threshold** in the Filter node to match your needs\n4. Activate the workflow \u2014 it runs daily at 7am automatically\n\n**Tip:** Change `buyer-country IN (AUT)` to any EU country code to monitor other markets."
      },
      "typeVersion": 1
    },
    {
      "id": "813e1118-54aa-409e-a090-f7ba151c95e4",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2864,
        1328
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "content": "## Fetch & Split\nFetches today's Austrian tenders from TED API and splits the `notices` array into individual items.\n\n\u26a0\ufe0f Date uses `$now.toFormat('yyyyMMdd')` \u2014 always dynamic, no duplicates."
      },
      "typeVersion": 1
    },
    {
      "id": "c41dbec1-486f-484b-bbd4-bb41642ff0d9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3472,
        1328
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "content": "## Filter & Loop\nRemoves already-awarded contracts. Loops remaining open tenders with 2s wait nodes to avoid rate limit errors on TED and easybits APIs."
      },
      "typeVersion": 1
    },
    {
      "id": "fb52acaa-5394-46f7-9ec6-53df4a366b42",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4128,
        1328
      ],
      "parameters": {
        "color": 7,
        "width": 972,
        "content": "## Extract & Notify\nDownloads each PDF and extracts structured data via easybits.tech. Filters for contracts \u2265 \u20ac100k and sends a Slack alert with title, authority, value, deadline, CPV, contact and PDF link."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "2ac4c01e-77af-4e25-b29e-f3a0966db3ed",
  "connections": {
    "Daily 7am Trigger": {
      "main": [
        [
          {
            "node": "Fetch Austrian Tenders from TED",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Tenders": {
      "main": [
        [],
        [
          {
            "node": "Loop Over Tenders",
            "type": "main",
            "index": 0
          },
          {
            "node": "Rate Limit: TED API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Tender PDF": {
      "main": [
        [
          {
            "node": "Rate Limit: easybits API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rate Limit: TED API": {
      "main": [
        [
          {
            "node": "Download Tender PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rate Limit: easybits API": {
      "main": [
        [
          {
            "node": "easybits - Extract a document",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Notices into Items": {
      "main": [
        [
          {
            "node": "Filter: Open Tenders Only",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter: Open Tenders Only": {
      "main": [
        [
          {
            "node": "Loop Over Tenders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter: Min. \u20ac100k Value": {
      "main": [
        [
          {
            "node": "Send Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "easybits - Extract a document": {
      "main": [
        [
          {
            "node": "Filter: Min. \u20ac100k Value",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Austrian Tenders from TED": {
      "main": [
        [
          {
            "node": "Split Notices into Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}