# Bandi Gara (`dome46/bandi-gara`) Actor

Extracts public procurement tenders (bandi di gara) from Lombardy's Sintel portal. Filter by keyword, date range, amount, or CPV category. Deduplicated across runs by tender ID (CIG).

- **URL**: https://apify.com/dome46/bandi-gara.md
- **Developed by:** [Domenico Montesanto](https://apify.com/dome46) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $35.00 / 1,000 bando estrattos

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

### What does Bandi di Gara Lombardia Scraper do?

**Bandi di Gara Lombardia Scraper** extracts public **procurement notices (bandi di gara)** published by public bodies in the Lombardy region of Italy, via the official [Sintel e-procurement portal](https://www.sintel.regione.lombardia.it/eprocdata/sintelSearch.xhtml). For each notice it returns the CIG (tender identification code), the awarding authority, the object of the tender, its category, amount, procedure type, publication/deadline dates, status, a link to the notice, and — when available — the awarded company. Results are automatically de-duplicated across runs, cross-checked against Lombardy's official open-data portal, and delivered as a ready-to-use Apify Dataset you can export as JSON, CSV, Excel, or query over the API — no code required. Runs on the Apify platform benefit from scheduling, monitoring, and integrations (Zapier, Make, Google Sheets, webhooks) out of the box.

### Why use Bandi di Gara Lombardia Scraper?

- **Business development & sales intelligence** — monitor new public tenders in your sector or geographic area to spot leads before competitors.
- **Legal & compliance teams** — track procedures involving specific public entities or CPV categories.
- **Journalists & researchers** — analyze public spending patterns, procedure types, and awarded companies over time.
- **Procurement consultants** — build a searchable, filterable archive of Lombardy tenders without manually browsing the Sintel portal.

### How to use Bandi di Gara Lombardia Scraper

1. Click **Try for free** or **Start** on the Actor page.
2. In the **Input** tab, optionally set filters: a keyword, a date range, a minimum/maximum amount, or one or more CPV categories.
3. Click **Start** and wait for the run to finish.
4. Open the **Dataset** tab (or the **Output** tab) to browse, filter, and export the results.
5. Schedule the Actor to run periodically to get only the *new* tenders on each run — already-seen tenders (tracked by CIG) are skipped automatically.

#### Using it from an AI agent (MCP)

This Actor exposes a plain JSON input/output contract, so it can be called directly as a tool by an MCP-connected agent (e.g. Claude) via the [Apify MCP server](https://mcp.apify.com/). Pass any subset of the input fields below; omitted fields mean "no filter on this dimension". The Actor returns structured dataset items — no HTML or free text to parse.

### Input

| Field | Type | Description |
|---|---|---|
| `regione` | string (select) | Region to scrape. Currently only `"Lombardia"` is supported. |
| `categoriaCPV` | array of strings | CPV codes or category keywords to filter by (best-effort text match). Leave empty for no filter. |
| `importoMinimo` | number | Minimum tender amount in EUR. |
| `importoMassimo` | number | Maximum tender amount in EUR. |
| `parolaChiave` | string | Free-text search on the tender's object/title. |
| `dataDa` | date | Only include tenders published on or after this date. |
| `dataA` | date | Only include tenders published on or before this date. |

See the **Input** tab for the interactive form, or call the Actor via the API with a JSON body matching the table above.

### Output

Each dataset item looks like this:

```json
{
  "CIG": "BCC47E51A0",
  "ente_appaltante": "Comune di Pompiano",
  "comune": "Pompiano",
  "provincia": null,
  "oggetto": "Servizio di manutenzione impianto rilevazione incendio scuola primaria, palestra e mensa",
  "categoria_cpv": "servizi di riparazione e manutenzione di impianti antincendio.",
  "importo": 5303.90,
  "tipo_procedura": "Affidamento diretto",
  "data_pubblicazione": "2026-08-24",
  "data_scadenza": "2026-08-25",
  "stato": "Aggiudicata",
  "url_bando": "https://www.sintel.regione.lombardia.it/eprocdata/auctionDetail.xhtml?id=223455021",
  "aggiudicatario": null,
  "fonte": "sintel_scraping"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel from the **Export results** button in the Apify Console, or via the API.

#### Data fields

| Field | Description |
|---|---|
| `CIG` | Tender identification code (Codice Identificativo Gara), when assigned. |
| `ente_appaltante` | Name of the awarding public authority. |
| `comune` | Municipality, best-effort extracted from the authority name when it follows the "Comune di X" pattern; `null` otherwise (neither source publishes a structured municipality field). |
| `provincia` | Not published by either source; always `null` for now. |
| `oggetto` | Object/title of the tender. |
| `categoria_cpv` | Merchandise category (numeric CPV code when available from open-data enrichment, otherwise the free-text category label). |
| `importo` | Tender amount in EUR. |
| `tipo_procedura` | Procedure type (e.g. "Affidamento diretto", "Procedura Aperta"). |
| `data_pubblicazione` | Publication date (ISO 8601). |
| `data_scadenza` | Bid submission deadline (ISO 8601). |
| `stato` | Procedure status (e.g. "Pubblicata", "Aggiudicata", "Chiusa"). |
| `url_bando` | Link to the tender's detail page on Sintel. |
| `aggiudicatario` | Awarded company name, when available (open-data enrichment only — Sintel's own detail page never exposes it). |
| `fonte` | `sintel_scraping` (primary source) or `open_data` (secondary, only used for closed/awarded procedures). |

Note: the tender's **RUP** (responsible officer, a named individual) is intentionally **not** extracted, as it is personal data.

### Pricing / Cost estimation

This Actor uses **pay-per-event** pricing: you are charged once per newly-discovered tender (identified by CIG) actually added to the dataset. Tenders already seen in a previous run are skipped and never charged again. There is no charge for empty runs or for re-running with the same date range once everything has already been collected.

### Tips or advanced options

- Narrow `dataDa`/`dataA` to a recent window on scheduled runs to keep each run fast and cheap — the CIG-based deduplication already prevents duplicate charges, but a tight date range also reduces the number of Sintel pages fetched.
- `categoriaCPV` and the amount filters are applied after fetching each tender's detail page, since Sintel's own search form doesn't expose a documented server-side filter for either. A very specific `parolaChiave` narrows the Sintel search itself and is the fastest way to cut run time.
- Set the `SOCRATA_APP_TOKEN` environment variable (a free token from the [Socrata developer portal](https://dev.socrata.com/docs/app-tokens.html)) if you rely heavily on the open-data enrichment step and hit rate limits.

### FAQ, disclaimers, and support

This Actor only extracts data that is already public: procurement notices published by public bodies under Italian transparency law. It does not collect personal data beyond what public bodies themselves publish, and explicitly excludes the RUP (responsible officer) name. Always check the current Terms of Service of the source sites before large-scale or commercial use.

The secondary open-data source (`dati.lombardia.it`) has shown data-quality issues in past verification (stale records, missing award dates, masked CIGs on records with zero amounts) — this Actor never uses it as the sole source for open/active tenders, only to enrich or supplement Sintel-scraped and already-closed procedures.

Found a bug or have a feature request? Use the **Issues** tab on this Actor's page. For custom scraping solutions, get in touch via the Apify platform.

# Actor input Schema

## `regione` (type: `string`):

Regione per cui estrarre i bandi. Solo Lombardia è supportata al momento; l'elenco verrà ampliato in futuro.

## `categoriaCPV` (type: `array`):

Codici o parole chiave di categoria CPV su cui filtrare (facoltativo). Lascia vuoto per non filtrare per categoria.

## `importoMinimo` (type: `integer`):

Importo minimo del bando, in euro. Lascia vuoto per non impostare un minimo.

## `importoMassimo` (type: `integer`):

Importo massimo del bando, in euro. Lascia vuoto per non impostare un massimo.

## `parolaChiave` (type: `string`):

Testo libero da cercare nell'oggetto del bando (full-text).

## `dataDa` (type: `string`):

Includi solo bandi pubblicati a partire da questa data.

## `dataA` (type: `string`):

Includi solo bandi pubblicati fino a questa data.

## Actor input object example

```json
{
  "regione": "Lombardia",
  "categoriaCPV": [],
  "parolaChiave": ""
}
```

# Actor output Schema

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

No description

# 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 = {
    "regione": "Lombardia",
    "categoriaCPV": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("dome46/bandi-gara").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 = {
    "regione": "Lombardia",
    "categoriaCPV": [],
}

# Run the Actor and wait for it to finish
run = client.actor("dome46/bandi-gara").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "regione": "Lombardia",
  "categoriaCPV": []
}' |
apify call dome46/bandi-gara --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dome46/bandi-gara"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/nr4gzWEE5DkF2SKhP/builds/2hlKarpnBWkmXs77G/openapi.json
