{
  "openapi": "3.0.1",
  "info": {
    "title": "EU & UK Tender Monitor",
    "description": "New public tenders from TED (EU), TenderNed (NL), BOAMP (FR) and Doffin (NO) in one English feed. One keyword, 5 languages, no duplicates.",
    "version": "0.1",
    "x-build-id": "eofbtLZXReuN3kmQp"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/mikee368~eu-tender-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-mikee368-eu-tender-monitor",
        "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/mikee368~eu-tender-monitor/runs": {
      "post": {
        "operationId": "runs-sync-mikee368-eu-tender-monitor",
        "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/mikee368~eu-tender-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-mikee368-eu-tender-monitor",
        "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": {
          "sources": {
            "title": "Sources",
            "type": "array",
            "description": "Which tender portals to query. TED = EU-wide (above EU thresholds), TENDERNED = Netherlands, BOAMP = France (incl. small MAPA tenders), DOFFIN = Norway (works with the Actor's shared key, 10 searches per run; your own free doffinApiKey gives more). SAM_GOV = US federal contract opportunities (optional, needs your own free SAM.gov API key; not selected by default). UK_FTS = UK Find a Tender (above and below threshold; no key; not selected by default; Open Government Licence v3.0). UK_CF = UK Contracts Finder (below-threshold; no key; not selected by default; same OGL v3.0; folded into Find a Tender when the procedure is the same). PL_BZP = Polish below-threshold notices from the free e-Zamówienia BZP API (no key; not selected by default; above-threshold Polish notices stay on TED). SIMAP = Swiss notices from simap.ch (no key; not selected by default; text kept as published, with simap's disclaimer).",
            "items": {
              "type": "string",
              "enum": [
                "TED",
                "TENDERNED",
                "BOAMP",
                "DOFFIN",
                "SAM_GOV",
                "UK_FTS",
                "UK_CF",
                "PL_BZP",
                "SIMAP"
              ],
              "enumTitles": [
                "TED (EU, all countries)",
                "TenderNed (Netherlands)",
                "BOAMP (France)",
                "Doffin (Norway, API key needed)",
                "SAM.gov (US federal, API key needed)",
                "Find a Tender (UK, no key needed)",
                "Contracts Finder (UK, below threshold, no key)",
                "e-Zamówienia BZP (Poland, below threshold, no key)",
                "simap.ch (Switzerland, no key)"
              ]
            },
            "default": [
              "TED"
            ]
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Optional keywords in English (any match). With 'Expand keywords' on, each keyword is expanded offline to Dutch, French, Norwegian and German equivalents (curated sector map: software, cloud, cybersecurity, cleaning, construction, catering …) and to matching CPV codes from the official CPV list. Each portal is searched in its own language(s). Unknown words are searched literally.",
            "default": [
              "software"
            ],
            "items": {
              "type": "string"
            }
          },
          "expandKeywords": {
            "title": "Expand keywords to NL/FR/NO/DE",
            "type": "boolean",
            "description": "Translate each keyword offline into the portal languages via a curated synonym map (e.g. software → software/programmatuur (NL), logiciel/progiciel (FR), programvare (NO), Software (DE)). Turn off to search keywords literally.",
            "default": true
          },
          "keywordCpvMatch": {
            "title": "Also match CPV codes derived from keywords (TED)",
            "type": "boolean",
            "description": "Look the keyword up in the official multilingual CPV 2008 list and also return TED notices classified under those codes (e.g. software → 48*, 722*), even if the text uses other words.",
            "default": true
          },
          "strictMatch": {
            "title": "Strict keyword match",
            "type": "boolean",
            "description": "On (default): keep only notices whose title, short description or CPV codes match your keywords (or the CPV codes derived from them). Off: also keep notices that a portal's full-text search matched somewhere deep in the notice; these are flagged matchType = full-text-only and get relevance 10.",
            "default": true
          },
          "mergeDuplicates": {
            "title": "Merge cross-portal duplicates",
            "type": "boolean",
            "description": "Merge a national notice (BOAMP, TenderNed, Doffin, Polish BZP, simap) into the TED notice for the same tender: exact match on eForms procedure/notice IDs where the portal publishes them, otherwise fuzzy match on buyer + title backed by deadline or CPV. Contracts Finder is folded into Find a Tender when the OCDS ocid matches. The merged row lists all portals in 'sources' and 'alsoPublishedOn'. SAM.gov and Find a Tender are never merged into TED.",
            "default": true
          },
          "cpvPrefixes": {
            "title": "CPV code prefixes",
            "type": "array",
            "description": "Optional CPV filter by prefix, so '72' matches every IT-services sub-code (72000000, 72212000, …). Up to 8 digits.",
            "items": {
              "type": "string"
            }
          },
          "countries": {
            "title": "Buyer countries (ISO 3166 alpha-3)",
            "type": "array",
            "description": "Optional filter on the buyer's country, e.g. NLD, FRA, DEU, NOR (2-letter codes such as NL or FR also work). Applied to TED in the query; national portals are dropped if their country is not listed.",
            "items": {
              "type": "string"
            }
          },
          "dateFrom": {
            "title": "Published on or after",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string",
            "description": "Leave EMPTY for incremental monitoring (recommended): each run starts from the day of the previous successful run of this Monitor ID, and already-seen notices are skipped. The first run looks back 'First-run lookback' days. Set a date (YYYY-MM-DD) only for one-off backfills."
          },
          "firstRunLookbackDays": {
            "title": "First-run lookback (days)",
            "minimum": 0,
            "maximum": 90,
            "type": "integer",
            "description": "How many days back the very first run of a Monitor ID searches when 'Published on or after' is empty.",
            "default": 3
          },
          "maxItemsPerSource": {
            "title": "Max notices per source",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Hard cap per source, which also caps cost.",
            "default": 5
          },
          "excludeAwards": {
            "title": "Skip award notices",
            "type": "boolean",
            "description": "Drop contract-award / result notices so you only get open calls, prior information and corrections.",
            "default": true
          },
          "translateTitles": {
            "title": "English titles (offline translation)",
            "type": "boolean",
            "description": "Fill 'titleEn': English original where the notice has one; otherwise offline machine translation for Dutch, French and Norwegian (OPUS-MT models, no external API); otherwise the English CPV label as fallback.",
            "default": false
          },
          "onlyNew": {
            "title": "Only new notices (monitor mode)",
            "type": "boolean",
            "description": "Remember notice IDs between runs (per Monitor ID) and output only notices not seen before. Default on; combine with an empty 'Published on or after' for a clean incremental feed.",
            "default": true
          },
          "monitorId": {
            "title": "Monitor ID",
            "type": "string",
            "description": "Name for this monitor's memory. Use different IDs for different saved searches so they don't share 'seen' lists.",
            "default": "default"
          },
          "resetState": {
            "title": "Reset monitor memory",
            "type": "boolean",
            "description": "Forget the seen notices and last-run time of this Monitor ID before running (starts again with the first-run lookback).",
            "default": false
          },
          "createDigest": {
            "title": "Write alert digest",
            "type": "boolean",
            "description": "Store a DIGEST record per run (counts per source, list of new notices, ready-made email subject/text/HTML) in the run's key-value store.",
            "default": true
          },
          "webhookUrl": {
            "title": "Webhook URL (optional)",
            "type": "string",
            "description": "If set, the DIGEST JSON is POSTed here at the end of each run that found new notices (e.g. a Make, Zapier, n8n or Slack-workflow webhook that emails or posts it)."
          },
          "notifyWhenEmpty": {
            "title": "Notify even when nothing new",
            "type": "boolean",
            "description": "Also call the webhook when a run finds 0 new notices.",
            "default": false
          },
          "digestEmailTo": {
            "title": "Digest e-mail recipient (optional)",
            "type": "string",
            "description": "Copied into DIGEST.email.to so your webhook/automation knows where to send it. The Actor itself does not send e-mails."
          },
          "doffinApiKey": {
            "title": "Doffin API key (optional, for higher limits)",
            "type": "string",
            "description": "Optional. Without a key the Actor uses its shared Doffin key (max 10 Doffin searches per run). For higher limits (30 per run, your own quota) enter your own free key from the Doffin developer portal (dof-notices-prod-api.developer.azure-api.net: sign up, subscribe to 'Public Api', copy the primary key). Doffin data: Source: Doffin (DFØ), CC BY 4.0."
          },
          "samGovApiKey": {
            "title": "SAM.gov API key (optional)",
            "type": "string",
            "description": "Your own free public API key from SAM.gov (sign in, then Account Details > Public API Key). Needed only for the SAM_GOV source; without it SAM.gov is skipped. A basic key allows about 10 requests per day, which is enough for a daily monitor."
          },
          "naicsCodes": {
            "title": "SAM.gov NAICS codes (optional)",
            "type": "array",
            "description": "Only for SAM_GOV: US NAICS codes (2-6 digits, e.g. 541511 = custom computer programming). One SAM.gov request per code; your keywords are then matched on the notice title.",
            "items": {
              "type": "string"
            }
          },
          "samGovMaxRequests": {
            "title": "SAM.gov requests per run",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Hard cap on SAM.gov API calls per run, to stay within your key's daily quota (basic keys: about 10/day). Each call returns up to 1,000 notices. If the cap stops a run early, the next run continues from the same date.",
            "default": 3
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}