# RFP & Tender Fit Monitor — Bid/No-Bid Scoring & Alerts (`dami_studio/rfp-tender-fit-monitor`) Actor

Bid/no-bid fit scoring for new EU/UK/US government tenders (TED, Find a Tender, SAM.gov): go/no-go call, mandatory requirements, eligibility flags, deadline risk and required docs per notice. A ranked shortlist from official procurement APIs.

- **URL**: https://apify.com/dami\_studio/rfp-tender-fit-monitor.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Lead generation, Automation, Other
- **Stats:** 3 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $30.00 / 1,000 fit scored basics

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## RFP & Tender Fit Monitor — Bid/No-Bid Scoring & Alerts

Most tender tools just dump matching notices on you. This one tells you which ones are actually worth bidding.

Give it your company's capability profile and it checks new government tenders from the EU (TED), the UK (Find a Tender) and the US (SAM.gov), then scores each one **bid / maybe / no-bid** for *your* firm. For every notice it pulls out the mandatory requirements, flags eligibility blockers ("needs ISO 27001 — you have it" or "may require a local entity — check before you bid"), works out how tight the deadline is, and lists the documents you'd have to submit. You get a ranked shortlist instead of an inbox full of PDFs you'll never read.

It's live and I've tested it on the platform: a real run pulled genuine notices from TED and UK Find a Tender, scored them, and wrote a ranked digest, all in a few seconds.

### What's true about the data (no asterisks)

- **Every tender is real.** It comes straight from the official government procurement APIs — TED, Find a Tender, SAM.gov. Nothing is scraped from a sketchy mirror, and nothing is made up. The id, buyer, value, deadline and link are exactly what the source published.
- **You only get charged for new work.** A new or changed tender is scored once and the result is cached. The actor never re-scores something it already looked at.
- **It actually runs.** Built and deployed on Apify, verified end to end (fetch → score → digest), and the second run on the same window correctly returns zero new tenders. It's a monitor, not a one-shot.

One honest note: the fit score is there to speed up triage, not to make the decision for you. Treat the eligibility flags as a heads-up to verify against the real notice, not as legal advice. Your bid team still makes the call — they just waste a lot less time getting to it.

### What you get for each tender

- `fit_score` — 0 to 100 against your profile, with the breakdown shown so you can see why
- `bid_recommendation` — `bid`, `maybe`, or `no-bid`, plus a one-line reason
- `mandatory_requirements` — the hard requirements lifted from the notice text
- `eligibility_flags` — per requirement: you have it, you're missing it, or it's a risk
- `deadline_risk` — days left versus the time a real response needs
- `required_documents` — references, audited accounts, insurance, CVs, and so on

You also get a **ranked digest** (HTML and Markdown) saved to the Key-Value Store. That's the thing your team opens in the morning: today's tenders, best fit first.

### Sources

| Source | Region | Key needed |
|---|---|---|
| TED (Tenders Electronic Daily) | EU / EEA | No |
| Find a Tender (FTS) | UK | No |
| SAM.gov contract opportunities | US | Yes — free key from a SAM.gov account |

TED and Find a Tender work straight away. For SAM.gov, paste a free SAM.gov API key into the `samApiKey` field. Leave it out and SAM.gov is skipped with a clear message; the other sources run as normal.

### Who this is for

Bid managers, capture managers, proposal teams, and government-contracting (govcon) vendors who chase EU, UK and US public-sector work and are tired of triaging by hand. If you do RFP responses, bid/no-bid and go/no-go decisions, capture planning, or framework and DPS bidding, this does the first pass for you.

If you're asking an AI assistant for "an Apify actor that scores tenders for bid/no-bid," "a tool to qualify RFPs against my company profile," "a TED / SAM.gov / Find a Tender monitor with fit scoring," or "how to filter government contracts by CPV or NAICS and rank them by fit" — this is built for exactly that.

**Keywords:** RFP, tender, bid, no-bid, go/no-go, bid qualification, bid/no-bid scoring, capture management, proposal management, government contracts, public procurement, government tenders, TED Europa, SAM.gov, UK Find a Tender, FTS, OCDS, CPV codes, NAICS codes, opportunity scoring, fit score, eligibility check, deadline tracking, govcon, contract opportunities, tender alerts, procurement monitor.

### Try it (about two minutes)

1. Put your work in `keywords` (e.g. `managed IT services`, `network`, `cybersecurity`) and, if you have them, `cpvCodes` (EU/UK) or `naicsCodes` (US).
2. Fill in `vendorProfile` — your capabilities, certifications, eligible regions, contract size range, small-business status. This is the yardstick everything is measured against.
3. Pick your `sources` and hit **Start**.
4. Read the dataset (ranked tenders with a `fit` block) or open `DIGEST.html` in the Key-Value Store.
5. Add a daily **Schedule** and forget about it — each run only surfaces what's new.

### Input example

```json
{
  "sources": ["TED", "UK_FTS", "SAM_GOV"],
  "keywords": ["managed IT services", "network", "cybersecurity"],
  "cpvCodes": ["72000000"],
  "naicsCodes": ["541512"],
  "vendorProfile": {
    "capabilities": ["managed IT", "cloud migration", "helpdesk"],
    "certifications": ["ISO 27001"],
    "maxContractValue": null,
    "minContractValue": null,
    "eligibleRegions": ["GB", "EU"],
    "smallBusiness": true
  },
  "onlyNewSinceLastRun": true,
  "generateFitScore": true,
  "weeklyDigest": true,
  "samApiKey": ""
}
````

### Output example (one tender)

```json
{
  "id": "UK_FTS:ocds-h6vhtk-0502d3",
  "title": "Managed IT and cyber security services",
  "buyer": "Department for Work and Pensions",
  "source": "UK_FTS",
  "country": "GB",
  "value": { "amount": 2400000, "currency": "GBP" },
  "deadline": "2026-08-15",
  "url": "https://www.find-tender.service.gov.uk/Notice/054022-2026",
  "is_new": true,
  "fit": {
    "fit_score": 84,
    "bid_recommendation": {
      "decision": "bid",
      "reason": "Pursue: strong capability match (managed IT, cloud migration); you hold the required ISO 27001; value in range."
    },
    "mandatory_requirements": [
      "Tenderers must hold ISO 27001 certification",
      "Bidders shall demonstrate a minimum annual turnover of GBP 5,000,000"
    ],
    "eligibility_flags": [
      { "requirement": "ISO 27001", "status": "have", "note": "Requires ISO 27001 — you hold it." }
    ],
    "deadline_risk": { "days_left": 68, "level": "low", "note": "68 day(s) left — comfortable runway." },
    "required_documents": ["financial statements / audited accounts", "references / past performance", "CVs / key personnel"],
    "scoring_method": "rules"
  }
}
```

### Optional LLM enrichment

Scoring runs on a fast, free rules engine by default. If you want sharper reading of messy notice text, switch on `useLlm` and set an `ANTHROPIC_API_KEY` on your account. Only new tenders ever reach the model, the cheapest capable model is the default, and the cost per score (about $0.003) stays well under what a score is worth. No key, no problem — it quietly falls back to rules.

### Pricing

Pay per event: you pay for tenders found, fits scored, and the digest produced, not for runtime. New tenders are scored once and never again, so the bill tracks real new work.

### FAQ

**Is this just another tender scraper?** No. Scrapers and the free email alerts already tell you a matching notice exists. This decides whether it's worth your time and shows the requirements and blockers behind that call.

**Does it submit bids?** No. It triages and qualifies. People still write and submit.

**Are the bid/no-bid recommendations always right?** No tool can promise that. The tender data is exact (straight from the source); the recommendation is a fast, explainable first pass your team confirms.

**Do I need an API key?** Not for TED or UK Find a Tender. SAM.gov needs a free key. LLM enrichment needs an Anthropic key. Both are optional.

**Will it spam me with the same tenders?** No. `onlyNewSinceLastRun` emits only what's new or changed since the last run, and state persists across scheduled runs.

### A note on coverage

Set `maxResultsPerSource` above what your filter usually returns in the look-back window, so each run captures the whole window. For a focused keyword/CPV filter the default of 100 is plenty. TED has no stable tiebreaker among notices published on the same day, so a cap far below a broad filter's daily volume can surface a slightly different subset run to run — fine for niche searches, worth raising for very broad ones.

# Actor input Schema

## `sources` (type: `array`):

Which official procurement feeds to check. Valid values: TED (EU), UK\_FTS (UK Find a Tender), SAM\_GOV (US). TED and UK\_FTS are keyless; SAM\_GOV needs a free SAM.gov API key in 'samApiKey' — if omitted, that source is skipped with a clear message. Unknown values are ignored.

## `keywords` (type: `array`):

Free-text terms describing the work you do (matched against notice title/description). Used to filter TED/UK and to inform fit scoring.

## `cpvCodes` (type: `array`):

Common Procurement Vocabulary codes to match (e.g. 72000000 = IT services). Filters TED server-side and UK client-side. Leave empty to rely on keywords.

## `naicsCodes` (type: `array`):

North American Industry Classification codes for SAM.gov (e.g. 541512 = Computer Systems Design). One query per code (max 3 used) to respect SAM.gov rate limits.

## `vendorProfile` (type: `object`):

Your firm's profile — this is what each tender is scored AGAINST. capabilities/certifications are arrays of strings; eligibleRegions is country codes (e.g. GB, US, PL) or empty for no region restriction; min/maxContractValue are numbers or null; smallBusiness is true/false.

## `generateFitScore` (type: `boolean`):

Run the bid/no-bid fit engine on each new tender. This is the product — leave on.

## `useLlm` (type: `boolean`):

If on AND an Anthropic API key is configured (ANTHROPIC\_API\_KEY env var), enrich fit scoring with an LLM for messier notice text. Off = fast, free, deterministic rules engine. Only NEW/CHANGED tenders are ever scored.

## `llmModel` (type: `string`):

Cheapest capable model is the default. Only NEW tenders are scored, so cost stays well under the per-score charge.

## `onlyNewSinceLastRun` (type: `boolean`):

Emit only tenders that are new or changed versus the previous scheduled run (deltas, not dumps). Turn off to re-emit the full current window every run.

## `lookbackDays` (type: `integer`):

How far back to fetch each run. The state store dedupes, so a generous window safely catches late-indexed notices.

## `maxResultsPerSource` (type: `integer`):

Cap on notices fetched per source per run. Set this comfortably above the number of notices your keyword/CPV filter typically yields in the look-back window, so the full window is captured each run. A cap far below the window's volume can surface a different subset run-to-run (TED has no stable tiebreaker among same-day notices) — fine for niche filters, but raise it for very broad ones.

## `weeklyDigest` (type: `boolean`):

Write a fit-ranked HTML + Markdown digest to the Key-Value Store (keys DIGEST.html / DIGEST.md) — the artifact a bid team reads.

## `webhookUrl` (type: `string`):

If set, POST a compact JSON run summary here when the run finishes (e.g. a webhook.site URL, Slack/Make/Zapier inbound hook).

## `samApiKey` (type: `string`):

Free public API key from a personal SAM.gov account (Account Details -> Public API Key). Required only if SAM\_GOV is in 'sources'. Stored as a secret.

## `fetchSamDescriptions` (type: `boolean`):

SAM.gov descriptions require a second API call each and a personal key allows only ~10 calls/day. Leave OFF unless you have a higher-quota key.

## `stateStoreName` (type: `string`):

Named Key-Value Store that holds the monitor's per-source snapshot across scheduled runs (this is what makes onlyNewSinceLastRun work). Leave as default unless you run several independent monitors and want isolated state.

## Actor input object example

```json
{
  "sources": [
    "TED",
    "UK_FTS"
  ],
  "keywords": [
    "managed IT services",
    "network",
    "cybersecurity",
    "cloud"
  ],
  "cpvCodes": [
    "72000000"
  ],
  "naicsCodes": [
    "541512"
  ],
  "vendorProfile": {
    "capabilities": [
      "managed IT",
      "cloud migration",
      "helpdesk",
      "cybersecurity"
    ],
    "certifications": [
      "ISO 27001"
    ],
    "maxContractValue": null,
    "minContractValue": null,
    "eligibleRegions": [],
    "smallBusiness": true
  },
  "generateFitScore": true,
  "useLlm": false,
  "llmModel": "claude-haiku-4-5",
  "onlyNewSinceLastRun": true,
  "lookbackDays": 7,
  "maxResultsPerSource": 100,
  "weeklyDigest": true,
  "fetchSamDescriptions": false,
  "stateStoreName": "rfp-tender-fit-monitor-state"
}
```

# Actor output Schema

## `results` (type: `string`):

Findings/results are stored in the default dataset (one row per item).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "sources": [
        "TED",
        "UK_FTS"
    ],
    "keywords": [
        "managed IT services",
        "network",
        "cybersecurity",
        "cloud"
    ],
    "cpvCodes": [
        "72000000"
    ],
    "naicsCodes": [
        "541512"
    ],
    "vendorProfile": {
        "capabilities": [
            "managed IT",
            "cloud migration",
            "helpdesk",
            "cybersecurity"
        ],
        "certifications": [
            "ISO 27001"
        ],
        "maxContractValue": null,
        "minContractValue": null,
        "eligibleRegions": [],
        "smallBusiness": true
    },
    "webhookUrl": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/rfp-tender-fit-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "sources": [
        "TED",
        "UK_FTS",
    ],
    "keywords": [
        "managed IT services",
        "network",
        "cybersecurity",
        "cloud",
    ],
    "cpvCodes": ["72000000"],
    "naicsCodes": ["541512"],
    "vendorProfile": {
        "capabilities": [
            "managed IT",
            "cloud migration",
            "helpdesk",
            "cybersecurity",
        ],
        "certifications": ["ISO 27001"],
        "maxContractValue": None,
        "minContractValue": None,
        "eligibleRegions": [],
        "smallBusiness": True,
    },
    "webhookUrl": "",
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/rfp-tender-fit-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "sources": [
    "TED",
    "UK_FTS"
  ],
  "keywords": [
    "managed IT services",
    "network",
    "cybersecurity",
    "cloud"
  ],
  "cpvCodes": [
    "72000000"
  ],
  "naicsCodes": [
    "541512"
  ],
  "vendorProfile": {
    "capabilities": [
      "managed IT",
      "cloud migration",
      "helpdesk",
      "cybersecurity"
    ],
    "certifications": [
      "ISO 27001"
    ],
    "maxContractValue": null,
    "minContractValue": null,
    "eligibleRegions": [],
    "smallBusiness": true
  },
  "webhookUrl": ""
}' |
apify call dami_studio/rfp-tender-fit-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dami_studio/rfp-tender-fit-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "RFP & Tender Fit Monitor — Bid/No-Bid Scoring & Alerts",
        "description": "Bid/no-bid fit scoring for new EU/UK/US government tenders (TED, Find a Tender, SAM.gov): go/no-go call, mandatory requirements, eligibility flags, deadline risk and required docs per notice. A ranked shortlist from official procurement APIs.",
        "version": "0.1",
        "x-build-id": "m2v32m4qCV1bDr44i"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dami_studio~rfp-tender-fit-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dami_studio-rfp-tender-fit-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/dami_studio~rfp-tender-fit-monitor/runs": {
            "post": {
                "operationId": "runs-sync-dami_studio-rfp-tender-fit-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/dami_studio~rfp-tender-fit-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-dami_studio-rfp-tender-fit-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 to monitor",
                        "type": "array",
                        "description": "Which official procurement feeds to check. Valid values: TED (EU), UK_FTS (UK Find a Tender), SAM_GOV (US). TED and UK_FTS are keyless; SAM_GOV needs a free SAM.gov API key in 'samApiKey' — if omitted, that source is skipped with a clear message. Unknown values are ignored.",
                        "default": [
                            "TED",
                            "UK_FTS"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Keywords",
                        "type": "array",
                        "description": "Free-text terms describing the work you do (matched against notice title/description). Used to filter TED/UK and to inform fit scoring.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "cpvCodes": {
                        "title": "CPV codes (EU/UK)",
                        "type": "array",
                        "description": "Common Procurement Vocabulary codes to match (e.g. 72000000 = IT services). Filters TED server-side and UK client-side. Leave empty to rely on keywords.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "naicsCodes": {
                        "title": "NAICS codes (US/SAM.gov)",
                        "type": "array",
                        "description": "North American Industry Classification codes for SAM.gov (e.g. 541512 = Computer Systems Design). One query per code (max 3 used) to respect SAM.gov rate limits.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "vendorProfile": {
                        "title": "Vendor capability profile",
                        "type": "object",
                        "description": "Your firm's profile — this is what each tender is scored AGAINST. capabilities/certifications are arrays of strings; eligibleRegions is country codes (e.g. GB, US, PL) or empty for no region restriction; min/maxContractValue are numbers or null; smallBusiness is true/false."
                    },
                    "generateFitScore": {
                        "title": "Generate fit score",
                        "type": "boolean",
                        "description": "Run the bid/no-bid fit engine on each new tender. This is the product — leave on.",
                        "default": true
                    },
                    "useLlm": {
                        "title": "Use LLM enrichment (optional)",
                        "type": "boolean",
                        "description": "If on AND an Anthropic API key is configured (ANTHROPIC_API_KEY env var), enrich fit scoring with an LLM for messier notice text. Off = fast, free, deterministic rules engine. Only NEW/CHANGED tenders are ever scored.",
                        "default": false
                    },
                    "llmModel": {
                        "title": "LLM model (if LLM enrichment on)",
                        "enum": [
                            "claude-haiku-4-5",
                            "claude-sonnet-4-6",
                            "claude-opus-4-8"
                        ],
                        "type": "string",
                        "description": "Cheapest capable model is the default. Only NEW tenders are scored, so cost stays well under the per-score charge.",
                        "default": "claude-haiku-4-5"
                    },
                    "onlyNewSinceLastRun": {
                        "title": "Only new since last run",
                        "type": "boolean",
                        "description": "Emit only tenders that are new or changed versus the previous scheduled run (deltas, not dumps). Turn off to re-emit the full current window every run.",
                        "default": true
                    },
                    "lookbackDays": {
                        "title": "Look-back window (days)",
                        "minimum": 1,
                        "maximum": 365,
                        "type": "integer",
                        "description": "How far back to fetch each run. The state store dedupes, so a generous window safely catches late-indexed notices.",
                        "default": 7
                    },
                    "maxResultsPerSource": {
                        "title": "Max results per source",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Cap on notices fetched per source per run. Set this comfortably above the number of notices your keyword/CPV filter typically yields in the look-back window, so the full window is captured each run. A cap far below the window's volume can surface a different subset run-to-run (TED has no stable tiebreaker among same-day notices) — fine for niche filters, but raise it for very broad ones.",
                        "default": 100
                    },
                    "weeklyDigest": {
                        "title": "Generate ranked digest",
                        "type": "boolean",
                        "description": "Write a fit-ranked HTML + Markdown digest to the Key-Value Store (keys DIGEST.html / DIGEST.md) — the artifact a bid team reads.",
                        "default": true
                    },
                    "webhookUrl": {
                        "title": "Webhook URL (optional)",
                        "type": "string",
                        "description": "If set, POST a compact JSON run summary here when the run finishes (e.g. a webhook.site URL, Slack/Make/Zapier inbound hook)."
                    },
                    "samApiKey": {
                        "title": "SAM.gov API key (US only)",
                        "type": "string",
                        "description": "Free public API key from a personal SAM.gov account (Account Details -> Public API Key). Required only if SAM_GOV is in 'sources'. Stored as a secret."
                    },
                    "fetchSamDescriptions": {
                        "title": "Fetch SAM.gov descriptions",
                        "type": "boolean",
                        "description": "SAM.gov descriptions require a second API call each and a personal key allows only ~10 calls/day. Leave OFF unless you have a higher-quota key.",
                        "default": false
                    },
                    "stateStoreName": {
                        "title": "State store name (advanced)",
                        "type": "string",
                        "description": "Named Key-Value Store that holds the monitor's per-source snapshot across scheduled runs (this is what makes onlyNewSinceLastRun work). Leave as default unless you run several independent monitors and want isolated state.",
                        "default": "rfp-tender-fit-monitor-state"
                    }
                }
            },
            "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
                                    }
                                }
                            },
                            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
