{
  "openapi": "3.0.1",
  "info": {
    "title": "German & EU Tenders: Public Procurement Monitor",
    "description": "German and EU public tenders in one deduplicated list: public procurement notices for Germany from oeffentlichevergabe.de (öffentliche Ausschreibungen, Vergabe) and TED, other EU countries via TED. Tenders scored to your CPV codes, keywords and regions, with deadlines. Daily tender alerts.",
    "version": "0.1",
    "x-build-id": "5NQj7e2IdFT1Vb5pZ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/lindenwerk~german-eu-tender-matcher/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-lindenwerk-german-eu-tender-matcher",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/lindenwerk~german-eu-tender-matcher/runs": {
      "post": {
        "operationId": "runs-sync-lindenwerk-german-eu-tender-matcher",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/lindenwerk~german-eu-tender-matcher/run-sync": {
      "post": {
        "operationId": "run-sync-lindenwerk-german-eu-tender-matcher",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "monitor",
              "backfill",
              "awards"
            ],
            "type": "string",
            "description": "monitor = only notices not returned by a previous run with the same stateKey (schedule it daily; this is the default when the field is omitted, e.g. in API calls). backfill = every notice in the date range dateFrom..dateTo (max 31 days; without dates: the last 7 days). awards = contract award notices only (who won what, for competitor tracking) in dateFrom..dateTo. The form opens with backfill so a first try shows the last 7 days right away; switch to monitor before you schedule it.",
            "default": "monitor"
          },
          "profileName": {
            "title": "Profile name",
            "type": "string",
            "description": "Free label for this search profile, copied to every output row (profileName). Also the default stateKey in monitor mode, so different profiles keep separate 'already seen' lists. Example: \"it-services-berlin\"."
          },
          "cpvCodes": {
            "title": "CPV codes (prefix match)",
            "type": "array",
            "description": "CPV classification codes or prefixes. A prefix matches every code that starts with it: \"72\" = all IT services, \"48\" = software packages, \"45\" = all construction works, \"909\" = cleaning services, \"7971\" = guarding / security services (Bewachung, not IT), \"4873\" = security software packages, \"72212730\" = security software development (for IT security, combine these with keywords). A main-CPV match gives the strongest score. Check digits like \"-8\" are ignored.",
            "items": {
              "type": "string"
            }
          },
          "keywords": {
            "title": "Keywords (German and/or English)",
            "type": "array",
            "description": "Words matched in title (full weight) and description (half weight). Case- and umlaut-insensitive. Keywords with 4+ letters also match inside German compound words (\"Software\" matches \"Softwareentwicklung\"); shorter ones (\"KI\", \"EDV\") match whole words only. Wrap a keyword in double quotes to force whole-word matching, e.g. \"\\\"Reinigung\\\"\". Rare keywords weigh more (BM25-style IDF). Keywords raise relevanceScore, so they interact with minScore: a CPV-only match scores 50, so a high minScore (60+) with only a few keywords can return nothing. Add more keyword variants (German and English) or lower minScore.",
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Exclude keywords",
            "type": "array",
            "description": "Notices whose title or description contains any of these words are dropped (never charged). Same matching rules as keywords. Example for a construction contractor: [\"Objektplanung\", \"Projektsteuerung\"].",
            "items": {
              "type": "string"
            }
          },
          "regions": {
            "title": "Regions (NUTS codes or German states)",
            "type": "array",
            "description": "Keep only notices whose buyer or place of performance lies in one of these regions. Accepts NUTS prefixes (\"DE3\" Berlin, \"DE21\" Oberbayern, \"DEA\" NRW, \"AT13\" Vienna) and German state names in German or English (\"Bayern\", \"Bavaria\", \"NRW\", \"Baden-Württemberg\"). Empty = no regional filter.",
            "items": {
              "type": "string"
            }
          },
          "contractTypes": {
            "title": "Contract types",
            "type": "array",
            "description": "Keep only these contract natures. works = construction works (Bauleistungen), services = services (Dienstleistungen), supplies = goods (Lieferungen). Empty = all.",
            "items": {
              "type": "string",
              "enum": [
                "works",
                "services",
                "supplies"
              ],
              "enumTitles": [
                "Works (Bauleistungen)",
                "Services (Dienstleistungen)",
                "Supplies (Lieferungen)"
              ]
            }
          },
          "minValue": {
            "title": "Minimum value (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Drop notices whose published estimated value (awards mode: awarded value) is below this amount. Notices without a published value are kept and flagged in matchReasons."
          },
          "maxValue": {
            "title": "Maximum value (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Drop notices whose published estimated value (awards mode: awarded value) is above this amount. Notices without a published value are kept."
          },
          "onlyOpen": {
            "title": "Only open tenders",
            "type": "boolean",
            "description": "Drop tenders whose submission/participation deadline has already passed. Tenders without a published deadline are kept (matchReasons says 'Deadline not published'). Ignored in awards mode.",
            "default": true
          },
          "minDaysUntilDeadline": {
            "title": "Minimum days until deadline",
            "minimum": 0,
            "maximum": 366,
            "type": "integer",
            "description": "Optional. Keep only notices whose deadline is at least this many days after the run (daysUntilDeadline >= value), e.g. 5 to skip tenders you cannot prepare in time. Days are counted from the run date to the submission deadline (the participation-request deadline when no submission deadline is published), the same number as the daysUntilDeadline output field. Empty = no filter (default). When set, notices without a published deadline are excluded. Filtered notices are never charged."
          },
          "maxDaysUntilDeadline": {
            "title": "Maximum days until deadline",
            "minimum": 0,
            "maximum": 366,
            "type": "integer",
            "description": "Optional. Keep only notices whose deadline is at most this many days after the run (daysUntilDeadline <= value), e.g. 21 = due within three weeks. Days are counted from the run date to the submission deadline (the participation-request deadline when no submission deadline is published), the same number as the daysUntilDeadline output field. Empty = no filter (default). When set, notices without a published deadline are excluded. Filtered notices are never charged."
          },
          "minScore": {
            "title": "Minimum relevance score (0-100)",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Only notices with relevanceScore >= minScore are returned (and charged as scored-match). Guide for a CPV + keyword profile: CPV match only = 50, one keyword in the title only = about 46, CPV + one title keyword = about 73. Use 40 for broad recall, 60 for precision. Keywords raise the score: with few keywords a high minScore can return nothing. Ignored when no CPV codes, keywords or competitor names are given.",
            "default": 40
          },
          "competitorNames": {
            "title": "Competitor names (awards mode)",
            "type": "array",
            "description": "Only return award notices won by an organisation whose name contains one of these strings (case-insensitive), e.g. [\"Muster Bau\", \"Beispiel IT\"]. Use together with mode = awards.",
            "items": {
              "type": "string"
            }
          },
          "lookbackDays": {
            "title": "Lookback days (monitor mode)",
            "minimum": 1,
            "maximum": 14,
            "type": "integer",
            "description": "Monitor mode: how many days back to look on each run. 1 = yesterday's German export plus TED from yesterday and today. Larger values are safe (already-seen notices are skipped) and protect against missed scheduled runs.",
            "default": 1
          },
          "dateFrom": {
            "title": "Date from (backfill/awards)",
            "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$",
            "type": "string",
            "description": "First publication day (YYYY-MM-DD) for backfill and awards mode. Default: dateTo minus 6 days. Ranges longer than 31 days are capped to the last 31 days."
          },
          "dateTo": {
            "title": "Date to (backfill/awards)",
            "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$",
            "type": "string",
            "description": "Last publication day (YYYY-MM-DD), inclusive. Default: today. The German export is only available up to yesterday."
          },
          "countries": {
            "title": "Buyer countries (TED)",
            "type": "array",
            "description": "ISO country codes of the buyers to include (two- or three-letter, e.g. DE, AT, FR, NL, PL). oeffentlichevergabe.de is used only when DE is in the list; other countries come from TED.",
            "default": [
              "DE"
            ],
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "title": "Sources",
            "type": "array",
            "description": "oeffentlichevergabe = German Bekanntmachungsservice (all German federal, state and municipal notices, including below EU thresholds). ted = Tenders Electronic Daily (EU-wide, above thresholds). Use both for full coverage; cross-posted notices are merged.",
            "items": {
              "type": "string",
              "enum": [
                "oeffentlichevergabe",
                "ted"
              ],
              "enumTitles": [
                "oeffentlichevergabe.de (Germany)",
                "TED (EU)"
              ]
            },
            "default": [
              "oeffentlichevergabe",
              "ted"
            ]
          },
          "noticeTypes": {
            "title": "Notice types",
            "type": "array",
            "description": "Which notice types to return. tender = open calls for tenders (default for monitor/backfill), award = contract awards (forced in awards mode), planning = prior information notices, modification = contract modifications, change = corrigenda.",
            "items": {
              "type": "string",
              "enum": [
                "tender",
                "award",
                "planning",
                "modification",
                "change"
              ],
              "enumTitles": [
                "Tender (call for competition)",
                "Award (result)",
                "Planning (prior information)",
                "Contract modification",
                "Change / corrigendum"
              ]
            }
          },
          "maxResults": {
            "title": "Max results",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum number of rows to return (and charge) in this run, best matches first. 0 = no limit. Default 500; the form prefills 25 for a cheap first try, so raise it (or set 0) for full results. The run also stops when your maximum total charge for the run is reached.",
            "default": 500
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "relevance",
              "deadline",
              "publicationDate"
            ],
            "type": "string",
            "description": "Order of the output rows: relevance (score desc, then earliest deadline), deadline (earliest first) or publicationDate (newest first).",
            "default": "relevance"
          },
          "includeDescription": {
            "title": "Include description",
            "type": "boolean",
            "description": "Include a shortened notice description in each row.",
            "default": true
          },
          "descriptionMaxLength": {
            "title": "Description max length",
            "minimum": 0,
            "maximum": 1500,
            "type": "integer",
            "description": "Maximum number of characters of the description per row.",
            "default": 500
          },
          "includeFunctionalContacts": {
            "title": "Include functional buyer e-mail",
            "type": "boolean",
            "description": "Include the buyer's functional contact (e.g. vergabestelle@city.de, 'Zentrale Vergabestelle'). Personal names, personal e-mail addresses (firstname.lastname@) and phone numbers are never output.",
            "default": true
          },
          "stateKey": {
            "title": "State key (monitor mode)",
            "type": "string",
            "description": "Name of the 'already seen' list kept in the named key-value store 'tender-matcher-state'. Default: the profile name. Use a different key per profile or per client."
          },
          "resetState": {
            "title": "Reset monitor state",
            "type": "boolean",
            "description": "Forget all notices seen by earlier runs with this stateKey before running (monitor mode).",
            "default": false
          },
          "firstRunBackfillDays": {
            "title": "First-run backfill days (monitor mode)",
            "minimum": 0,
            "maximum": 14,
            "type": "integer",
            "description": "Monitor mode: if a run without saved state (the very first run for this stateKey, or after Reset monitor state) finds nothing new in its lookback window, for example because it starts on a weekend or holiday, it looks back this many days once instead, so you see the current open tenders. Later runs are normal monitor runs. 0 = off.",
            "default": 7
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}