ParseForge Scrapers

ANAC Italy Public Procurement Scraper - Tenders & Awards

parseforge/anac-italy-procurement-scraper

BusinessDeveloper toolsOther

Italian public tenders (CIG), awards, bidders, subcontracts, contract lifecycle, 48k contracting authorities, SOA certificates and OCDS releases from ANAC open data.

Run this scraper See the API call
Total runs
22
Bookmarked
0
Last modified
8 days ago

This scraper was last updated on .

What does the ANAC Italy Public Procurement Scraper - Tenders & Awards return?

ParseForge

ANAC Italy Public Procurement Scraper - Tenders & Awards

Scrape the whole ANAC open-data portal: every Italian public tender, award, bidder and contract event since 2007. 31 tables behind one input: tenders (CIG), SmartCIG, awards, winners, losing bidders, subcontracts, the full contract lifecycle, 48,000 contracting authorities, SOA qualification certificates and OCDS 1.1 releases. No login, no API key. Export to CSV, JSON, Excel or XML.

dati.anticorruzione.it publishes Italy's entire public-procurement record, and publishes it as downloadable archives with no query API: CKAN's datastore extension is not installed, so datastore_search answers "Nome di azione non nota". Getting one region's works contracts out of it means downloading a whole month's ZIP and parsing 61 columns of SCREAMING_SNAKE mixed with snake_case. This Actor reads the archives straight off the wire, filters while they stream, and stops the transfer the moment your row cap is met: 20,000 tenders came back in 13 seconds having pulled 3.7 MB of a 22.7 MB archive.

Who uses it What they pull from ANAC
Procurement intelligence & bid platforms Live tender feed with CPV, value, buyer and deadline, the input to a bid-alert product
Anti-corruption researchers & journalists Single-bid awards, zero-discount awards, contract variations and subcontract chains
B2B sales & lead generation 48,000 contracting authorities with fiscal codes and addresses; which firms win what, from whom
Credit risk & supplier due diligence A company's full award history, its subcontracting network and its SOA qualification classes
Construction & works contractors Works tenders by SOA category and amount class, filtered by region and CPV
Public-spending analysts & academics PNRR-funded contracts, funding-source breakdowns, progress instalments and cost overruns
Open-contracting toolchains OCDS 1.1 releases, ready to join against other OCDS publishers with no mapping work

What it does

Pick one or more collections; the Actor returns one row per record, typed, with English aliases on top of ANAC's own Italian column names. Every row carries collection, sourceDataset, sourceUrl and period, so a multi-collection run stays separable.

  • ๐Ÿ“„ Tenders (CIG): 84 fields per lot: subject, value, procedure, CPV, buyer, cost centre, region, publication and outcome dates, PNRR flag, urgency grounds, delegation chain. Monthly archives back to 2007.
  • โšก SmartCIG, the simplified route for low-value contracts, back to 2011. Roughly as many rows again.
  • ๐Ÿ… Awards, winners and losing bidders, the awarded amount, the discount off the base price, how many firms bid, and every firm that did. This is the half most scrapers stop before.
  • ๐Ÿ”— The full contract lifecycle: start, end, suspensions, acceptance testing, progress instalments (SAL), variations, subcontracts, economic framework and funding sources. All keyed on cig.
  • ๐Ÿ›๏ธ 48,040 contracting authorities and 158,645 cost centres: AUSA code, fiscal code, VAT, legal nature, address, in-house and state-owned flags.
  • ๐Ÿ“œ SOA certificates, which firms may legally bid for works over EUR 150,000, with the exact categories and classes granted.
  • ๐ŸŒ OCDS 1.1 releases, the same processes in the international standard, streamed out of bulk files up to 3.2 GB each.
  • ๐Ÿ—‚๏ธ The catalogue itself: all 70 datasets and 1,703 distributions with DCAT-AP_IT metadata, plus the reference code tables that decode the numeric fields on tender rows.

Collections

Collection What one row is Coverage
tenders A tender lot with its CIG, 84 fields Monthly, 2007 โ†’ today
smart-tenders A SmartCIG low-value contract Monthly, 2011 โ†’ today
awards Award decision: amount, discount, bid counts Full table + monthly deltas
winners A firm that won a CIG Full table + monthly deltas
participants A firm that bid, losers included Full table + monthly deltas
contract-start Signature, enforceability, effective start Full table + monthly deltas
contract-end Completion, early termination, extensions Full table + monthly deltas
testing Acceptance testing, reserves, litigation value Full table + monthly deltas
suspensions Suspension with reason and resumption date Full table + monthly deltas
progress-reports One SAL instalment with amount and slippage Full table + monthly deltas
variants An approved variation and its legal ground Full table + monthly deltas
subcontracts Subject, category, and both firms Full table + monthly deltas
economic-framework Value split into works/services/supplies/design Full table + monthly deltas
funding-sources State, regional, local, EU, private, loans Full table + monthly deltas
publications Register, GURI, OJEU, regional bulletin dates Full table + monthly deltas
work-types Type of work under a CIG Full table + monthly deltas
work-categories SOA category (OG/OS) and amount class Full table + monthly deltas
dpcm-categories DPCM aggregation category and derogation Full table + monthly deltas
contracting-authorities A registered buyer 48,040 rows
cost-centres A purchasing unit inside a buyer 158,645 rows
cup-links CIG โ†’ CUP investment-project link 7,167,369 rows
pnrr-indicators Recovery-plan female and youth quotas 381,833 rows
soa-certificates A SOA qualification certificate 472,916 rows
soa-categories A category and class the certificate grants 1,774,956 rows
ocds-releases An OCDS 1.1 contracting process Monthly, 2018 โ†’ today
datasets A CKAN dataset with DCAT-AP_IT metadata 70 rows
resources A distribution with its direct URL and size 1,703 rows
organizations The publishing organisation 1 row
groups A DCAT theme group 13 rows
tags A tag or controlled-vocabulary term Tags + 6 vocabularies
reference-codes A procedure, delivery mode, SmartCIG type or licence 4 lookup tables

June 2025 alone holds 123,121 tenders. A whole year of tenders is over a million rows, which is why Max rows matters more here than on most Actors.

What you can do with ANAC data

๐Ÿ›๏ธ Build a bid-alert feed.

government contracts runs 18,100 searches a month in the US at a $5.33 CPC, and public procurement 480 at $15.35: this is a market that pays for leads. Set collections: ["tenders"], the current year and month, a CPV prefix and a minimum amount, and you have every matching Italian lot with its buyer, its value and its offer deadline.

๐Ÿšฉ Find the single-bid awards.

The awards collection carries bidsReceived and a derived singleBid flag, and Only single-bid awards turns it into a filter. One bidder on an open procedure is the first red flag in every procurement-integrity methodology there is; procurement red flags and open contracting are both live search terms. Cross it with discountPct: 0 and you have the classic pair.

๐Ÿ” Assemble one contract end to end.

Put a CIG in CIG codes, select awards, winners, participants, contract-start, progress-reports, variants and subcontracts, and you get the whole life of that contract in one dataset: who bid, who won, at what discount, when work started, every instalment paid, every variation approved and every firm subcontracted. No other ANAC Actor on the Store joins those tables.

๐Ÿข Profile a supplier.

Put a company's partita IVA in Fiscal codes and run winners, participants and subcontracts: every contract it won, every one it bid for and lost, and every job it took as a subcontractor. Add soa-certificates and soa-categories for what it is legally qualified to bid on. That is a due-diligence file most credit-risk vendors sell by subscription.

๐Ÿ“‡ Export the buyer list.

contracting-authorities is 48,040 Italian public buyers with fiscal code, VAT number, AUSA code, legal nature and street address, plus the in-house and state-owned flags: stazioni appaltanti is a 390-a-month Italian search on its own. One run, no filters, done.

๐Ÿ’ถ Follow the recovery-plan money.

Only PNRR / PNC contracts keeps just the tenders funded by Italy's Recovery and Resilience Plan: 5,414 of June 2025's 123,121. Add funding-sources for the state / regional / local / EU split, and pnrr-indicators for the female and youth employment quotas each one carries.

๐ŸŒ Skip the OCDS mapping.

ocds-releases hands you Open Contracting Data Standard 1.1 objects with ocid, awards, parties and CPV classification already in place, plus the CIGs of every lot so the rows join straight back to the Italian tables. ANAC publishes these as monthly JSON files of up to 3.2 GB; the Actor streams them and stops when your cap is met.

๐Ÿ‡ฎ๐Ÿ‡น Cover the Italian search demand.

anac alone is 110,000 searches a month in Italy, cig anac and subappalti 4,400 each, appalti pubblici 2,400, gare d'appalto 1,300, bandi di gara 590 and aggiudicazioni appalti 110. Every one of those is a collection in this Actor.

Why choose this scraper

What you get
31 collections, one Actor Every ANAC table, not just the tender list. Awards, bidders, subcontracts, lifecycle, buyers, SOA and OCDS.
The bidders, not just the winners participants carries the firms that lost, which is the only way to measure who competes against whom.
Streaming with early abort 20,000 tenders came back having transferred 3.7 MB of the 22.7 MB archive that holds all 123,121 rows for that month. You are not billed for bytes you never needed.
Filters that cut before billing Keyword, CIG, fiscal code, CPV, region, province, sector, procedure, amount, date, PNRR and single-bid, all applied while the file streams.
Typed, not raw strings Amounts as numbers, dates as ISO 8601, flag_* columns as real booleans, with English aliases on top of ANAC's Italian names.
History back to 2007 Every month of every year, picked with a year and month selector rather than a URL you have to guess.
No login, no API key Every surface is public and anonymous. Apify's own datacenter proxy is on by default because the portal blocks the platform's IP range, it costs nothing extra and needs no setup.
Only the columns that exist Columns ANAC ships in the header but never fills are not shipped as always-null fields. See the traps below.

Six traps this Actor handles for you

The portal rejects unknown clients, per path. dati.anticorruzione.it sits behind an F5 ASM WAF. A default curl gets Request Rejected with a support ID, and it is path-sensitive: the root rejects while /opendata answers. The Actor presents a browser client and reads only the paths that serve data.

The same WAF blocks Apify's own IP range. The identical request that passes from a workstation on a datacenter IP comes back HTTP 403 from an Apify container. It is the exit IP, not a rate limit, so waiting it out achieves nothing, and about two in three Apify datacenter proxy exits are refused as well. The Actor routes through Apify's datacenter proxy by default, rotates to a fresh session on every 403, and falls back to a direct connection when no proxy is available (which is what makes it work outside Apify). Residential is never requested: datacenter clears this WAF, so paying for residential would buy nothing. A run that is refused everywhere fails loudly rather than reporting success with an empty dataset.

Long downloads get cut off, so they resume. Reading these archives through a proxy means long-lived connections, and long-lived connections die: an OCDS read that ran to 33 MB from a workstation was killed at ~11 MB on the platform with other side closed. The portal answers accept-ranges: bytes, so a dropped transfer reopens with a Range request at the exact byte it stopped and the inflater and parser state carry straight on, they never see the seam. A trailing partial row is discarded rather than shipped as data.

stato is a constant, and the cancellation columns are empty. Every tender ANAC publishes carries stato: ATTIVO: 123,121 out of 123,121 in June 2025. The three cancellation columns (COD_MOTIVO_CANCELLAZIONE, MOTIVO_CANCELLAZIONE, DATA_CANCELLAZIONE) are empty in every row of 2015, 2020, 2023 and 2025 that we measured: about 245,000 rows. A revoked tender is recorded through ESITO instead, as "ANNULLATA/REVOCATA ...". So the empty columns are not shipped, outcome is lifted to the top of the row, and Exclude cancelled records reads the outcome. Filtering on stato would have silently returned everything.

The full snapshot does not exist for tenders. ANAC ships three shapes in the same catalogue: a full snapshot (aggiudicazioni_csv.zip), monthly incrementals (20260801-aggiudicazioni_csv.zip) and per-year monthly partitions (cig_csv_2025_06.zip). cig and smartcig publish only incrementals: their history lives in 19 separate per-year datasets. The Actor resolves the right shape per collection from the live catalogue instead of hard-coding URLs, and says in the log which files it chose.

A 3.2 GB JSON file will not fit in memory. The OCDS bulk files are single JSON documents up to 3.2 GB, and one framework-agreement release inside them can be 4 MB on its own. The Actor scans the byte stream incrementally and yields releases as they close, so peak memory stays flat regardless of file size. Releases over 512 KB come back as their lifted summary with releaseTruncated: true rather than blowing past the dataset item limit.

How it compares

Five other Actors scrape ANAC. All five are single-table tender scrapers; none of them publishes a README, so this table compares what their Store listing and pricing state.

Feature ParseForge (this) ayrtondavoli97 promptica fortuitous_pirate monkey.d.scraping apexforge
Collections 31 1 (tenders) 1 (tenders) 1 3 (tenders, awards, suppliers) 1 (tenders)
Losing bidders Yes No No No No No
Contract lifecycle (SAL, variations, suspensions) Yes No No No No No
Subcontracts Yes No No No No No
Contracting-authority registry 48,040 No No No No No
SOA qualification certificates Yes No No No No No
OCDS 1.1 output Yes No No No No No
History 2007 โ†’ Not stated Not stated Not stated 2007 โ†’ Not stated
Run-start fee $0.007 $0.10 $0.05 $0.05 $0.02 $0.005
Price per 1,000 tender rows $5.00 $2.00 $2.00 $3.50 $1.00 $8.00
1,000 tenders, all in $5.01 $2.10 $2.05 $3.55 $1.02 $8.01

We are the expensive option on a plain tender list, and that is deliberate. If all you need is 1,000 Italian tenders with CPV and value, monkey.d.scraping or promptica will do it for a third of the price and you should buy that. This Actor is priced for the 30 tables the others do not have: the losing bidders, the SAL instalments, the subcontract chain, the SOA classes, the 48,000-buyer registry and the OCDS output. The run-start fee is 7x to 14x below the two closest competitors, so small exploratory runs land cheaper here even at the higher row rate.

Why $5 per 1,000. This Actor is HTTP-only: no browser, no residential IPs, and the datacenter proxy it does use is included in every Apify plan. Measured on the platform 2026-08-27, its own running cost is $0.0054 per 1,000 rows (a 1,000-row tender run billed $0.005406 of compute, storage and transfer). The house floor is $5 per 1,000 and the ceiling is $7; because the competition is already below the floor, this sits at the floor rather than the target. The reference and classification tables are cheaper still ($2 to $4 per 1,000), and only the OCDS release: read out of multi-gigabyte files and carrying a nested object: costs more at $9.

What a row looks like

Tender (collections: ["tenders"]): 84 fields, abbreviated here:

{
  "collection": "tenders",
  "title": "INTERVENTO DI RECUPERO DEL CONTESTO PAESAGGISTICO DELLA FRAZIONE DI TRASSILICO",
  "amount": 38754.65,
  "currency": "EUR",
  "buyerName": "COMUNE DI GALLICANO",
  "buyerFiscalCode": "81000160465",
  "procedureType": "AFFIDAMENTO DIRETTO",
  "cpvCode": "45112000-5",
  "cpvDescription": "LAVORI DI SCAVO E MOVIMENTO TERRA",
  "sector": "LAVORI",
  "region": "TOSCANA",
  "province": "LUCCA",
  "publishedDate": "2025-01-24",
  "deadlineDate": "2025-01-23",
  "status": "ATTIVO",
  "outcome": "AGGIUDICATA",
  "outcomeDate": "2025-01-23",
  "isPnrr": false,
  "cig": "B552431AE5",
  "numeroGara": "start_17/01/2025 13:13:24_001700/2025",
  "importoComplessivoGara": 38754.65,
  "nLottiComponenti": 1,
  "importoLotto": 38754.65,
  "settore": "SETTORI ORDINARI",
  "luogoIstat": "046015",
  "codTipoSceltaContraente": "24",
  "modalitaRealizzazione": "CONTRATTO D'APPALTO",
  "codiceAusa": "0000239369",
  "sezioneRegionale": "SEZIONE REGIONALE TOSCANA",
  "idCentroCosto": "D4EC5B46-8752-49C6-B930-57944FB92EC9",
  "denominazioneCentroCosto": "SETTORE LAVORI PUBBLICI",
  "flagUrgenza": true,
  "motivoUrgenza": "NON APPLICABILE",
  "importoSicurezza": 1093.52,
  "flagPnrrPnc": false,
  "sourceDataset": "cig-2025",
  "sourceUrl": "https://dati.anticorruzione.it/opendata/download/dataset/cig-2025/filesystem/cig_csv_2025_01.zip",
  "period": "2025-01",
  "scrapedAt": "2026-08-27T14:11:55.650Z"
}

Award (collections: ["awards"]):

{
  "collection": "awards",
  "cig": "B30B340E7A",
  "awardAmount": 10400,
  "currency": "EUR",
  "discountPct": 0,
  "bidsReceived": 1,
  "singleBid": true,
  "awardedDate": "2024-09-13",
  "outcome": "AGGIUDICATA",
  "flagSubappalto": false,
  "astaElettronica": false,
  "idAggiudicazione": "22043751",
  "period": "20260801"
}

Contracting authority (collections: ["contracting-authorities"]):

{
  "collection": "contracting-authorities",
  "buyerName": "SCUOLA SECONDARIA STATALE DI I GRADO GIOVANNI XXIII",
  "buyerFiscalCode": "81002210649",
  "vatNumber": "00000000000",
  "ausaCode": "0000324784",
  "legalNature": "ENTI PUBBLICI NON ECONOMICI",
  "province": "AVELLINO",
  "city": "GROTTAMINARDA",
  "indirizzoOdonimo": "VIA ALCIDE DE GASPERI 23",
  "cap": "83035",
  "flagInHouse": false,
  "flagPartecipata": false,
  "status": "ATTIVO",
  "dataInizio": "2013-07-09T19:16:34Z"
}

SOA certificate (collections: ["soa-certificates"]):

{
  "collection": "soa-certificates",
  "supplierName": "FERRETTI S.R.L.",
  "supplierFiscalCode": "01838640991",
  "certifierName": "SOA RINA SPA",
  "certificateNumber": "7019",
  "status": "SCADUTO_5_ANNI",
  "province": "GENOVA",
  "validUntil": "2014-07-19",
  "ataAttestatoDataScadenzaValiditaTriennale": "2012-07-19",
  "ataAttestatoDataRilascioAttestazioneOriginaria": "2009-07-20"
}

OCDS release (collections: ["ocds-releases"]), the full release object rides along under release:

{
  "collection": "ocds-releases",
  "ocid": "ocds-hu01ve-CONSIP_ORDINE_8709430",
  "releaseId": "ocds-hu01ve-CONSIP_ORDINE_8709430-01",
  "title": "GASOLIO EXTRA RETE",
  "date": "2025-09-19T12:00:00Z",
  "awardAmount": 35000,
  "currency": "EUR",
  "buyerName": "FORMIA RIFIUTI ZERO SOCIETA' A RESPONSABILITA' LIMITATA",
  "buyerFiscalCode": "02796960595",
  "buyerAusaCode": "0000404831",
  "buyerLocality": "FORMIA",
  "supplierNames": ["Q8 QUASER S.R.L."],
  "supplierFiscalCodes": ["00295420632"],
  "cigs": ["B84F8F3C82"],
  "cpvCodes": ["09134100-8"],
  "cpvDescriptions": ["CARBURANTE DIESEL"],
  "awardCount": 1,
  "partyCount": 3,
  "releaseTruncated": false
}

Configure the run

Setting What it does
Collections Which of the 31 tables to pull. Each bills its own per-row event.
Which files to read Selected period reads the per-month archives (the only way to reach history); Latest monthly update reads the newest incremental; Full snapshot reads the complete table.
Years / Months Which months to read. Tenders go back to 2007, SmartCIG to 2011, OCDS to 2018. The current year appears only once ANAC creates its dataset: use Latest monthly update for the freshest records.
Max rows / Max rows per collection Hard caps. The download stops the moment the cap is met.
Keywords Substring match on subject, supplier and buyer names.
CIG codes Pin to specific tenders. Works across every procurement table: this is how you assemble one contract's lifecycle.
Fiscal codes / VAT numbers Match any party: buyer, winner, bidder, subcontractor. Punctuation and country prefixes ignored.
CPV codes Prefix match. 45 keeps all construction; 45112000-5 keeps just that class.
Regions / Provinces LOMBARDIA, SICILIA; MILANO or IT-MI.
Contract sector Works, services or supplies.
Procedure types By name (AFFIDAMENTO DIRETTO) or by ANAC code (24). Run reference-codes for the full table.
Status Substring match, including the award outcome. AGGIUDICATA, SCADUTO.
Min / Max amount On the contract or award value, in EUR.
Date from / to On the row's own publication, communication or award date.
Only PNRR / PNC Recovery-plan contracts only.
Only single-bid awards Awards that drew exactly one bidder. awards only: nothing else carries a bid count.
Exclude cancelled records Drops outcomes marked annulled or revoked.
Catalogue search / themes / formats CKAN full-text and facet filters, for the datasets and resources collections.
Include untouched source columns Adds a raw object with every column exactly as ANAC wrote it. Roughly doubles row size.
Include the full OCDS release Keeps the complete release object. On by default; dropped automatically below 512 MB of run memory.
Proxy On by default, and it must stay on for runs on Apify, the portal blocks the platform's IP range. Apify's datacenter proxy is enough and is included in your plan.

How filtering actually works

ANAC gives no server-side query, so filters run client-side while the archive streams. Two consequences worth knowing:

  • A narrow filter costs time, not money. Filtered-out rows are never written and never billed, but the file still has to stream past. Pinning one CIG in the awards table scanned 208,070 rows and pulled 5.4 MB before finding its match. That is the price of a source with no index.
  • OCDS is the slow one. The bulk files are uncompressed JSON (the server offers no gzip) and have to be read sequentially. Measured on the platform: 600 releases, 33.9 MB, 312 seconds. Budget roughly 2 releases a second and raise Scraping time budget for a large pull. Every other collection is 10x to 100x faster: 20,000 tenders came back in 13 seconds.
  • A filter naming a column this table does not have returns nothing, not everything. That is deliberate. A filter that silently matched every row would look exactly like a table with no matches, and you would only find out after paying for the rows.

To keep a filtered run bounded, set Scraping time budget (under Advanced). The Actor flushes what it has and exits cleanly when it expires, rather than being killed mid-write.

Free users

Apify's free plan caps what any paid Actor can bill in a month. If a run stops early with a usage message, that is the plan cap, not this Actor.

Separately, Apify gives every run a maximum cost derived from your remaining allowance and aborts the run when it reaches it, the run's status message names the figure. A year of tenders is over a million rows, which is more than enough to hit that. Set Max rows to keep a run inside a budget you choose, and it will finish cleanly instead of being aborted.

Run it

  1. Pick your Collections. Start with tenders.
  2. Choose Which files to read: Selected period plus a Year and Month for history, or Latest monthly update for the freshest delta.
  3. Narrow with CPV, region, amount or keywords if you want.
  4. Set Max rows for a hard ceiling on cost.
  5. Run, then export as CSV, JSON, Excel or XML: or pull it from the API.

The default input: 1,000 tenders from January 2025: returns in a few seconds having transferred well under a megabyte.

Troubleshooting

The run failed with "the ANAC portal refused every request". The proxy was turned off. Re-enable it: on Apify the portal blocks the platform's IP range outright. This is a hard failure by design, so it can never be mistaken for "ANAC has no data".

No rows came back. Check the log line for the collection: it prints how many rows it scanned and how many it kept. scanned high and kept zero means your filters excluded everything: start by dropping one. scanned zero means the file itself was empty or missing for that period.

"ANAC has not published cig for 2026 yet." The per-year tender datasets are created only once ANAC starts publishing that year, so the current year is usually missing for months: as of this writing cig-2026 and smartcig-2026 do not exist, while ocds-appalti-ordinari-2026 has January to March. The log names the years that do exist. For the newest tenders, set Which files to read to Latest monthly update, which reads ANAC's dated incremental and does carry the current year.

"No CSV distribution matched the requested period." That collection is not partitioned by month, so it ignores Years and Months: only tenders, smart-tenders and ocds-releases are. Switch Which files to read to Latest monthly update or Full snapshot.

Full snapshot gave me the latest update instead. ANAC publishes no full snapshot for cig or smartcig; their history is in the per-year datasets. The Actor warns and falls back. Use Selected period with a year to read history for those two.

Filtering by CIG is slow. There is no index, the archive has to stream past until the match is found. Narrow the period first, or raise Scraping time budget.

The OCDS release object is missing. Either the run has under 512 MB of memory, in which case the log says so and the summary fields are still there, or that release was over 512 KB and releaseTruncated is true.

A field I expected is null. ANAC leaves many columns sparse. codModalitaIndizioneServizi is filled on 0.035% of tenders, cuiProgramma on 1.8%. The columns that were empty on every row measured, the three cancellation fields, and seven DCAT slots on the catalogue: are not shipped at all, so a null you see is a genuine gap in one record rather than a dead column.

The run stopped before the last collection. Max rows is a global cap. Set Max rows per collection as well so one large table cannot consume the whole budget.

FAQ

Does it need a login or an API key? No. Every surface used here is public and anonymous.

Does it need a proxy? On Apify, yes, the portal's WAF returns HTTP 403 to the platform's own IP range. Apify's datacenter proxy clears it, is on by default and is included in every plan, so there is nothing to configure and no extra cost. Residential is not needed. Outside Apify the Actor falls back to a direct connection on its own.

How far back does it go? Tenders to 2007, SmartCIG to 2011, OCDS releases to 2018. The lifecycle tables are cumulative and reach back as far as ANAC's records do, the oldest suspension in a sample was from 2014.

Can I get the whole of 2025? Yes: select all twelve months and raise Max rows. That is over a million tender rows, so decide the budget first.

Why is the OCDS collection so much slower? Its source is a single uncompressed JSON file of up to 3.2 GB that has to be read from the start, and the server offers no gzip. It works: 600 releases in about five minutes, but raise Scraping time budget before asking for tens of thousands.

How current is it? ANAC publishes monthly. The lifecycle tables get a dated incremental on the 1st, and Latest monthly update always reads the newest one published. The per-year tender datasets lag: cig-YYYY is created only once ANAC starts publishing that year, so early in a year the current year has no per-month archive and Latest monthly update is the way to reach it.

Why is stato always ATTIVO? Because that is what ANAC publishes on every tender. The column that says how the procedure ended is esito, lifted to outcome on every row.

What is a CIG? The Codice Identificativo Gara, the identifier Italy assigns to every public tender lot. It is the join key for every procurement collection here, and it also appears inside the OCDS rows as cigs.

Is the data licensed for reuse? ANAC publishes the catalogue under CC BY-SA 4.0. The datasets collection carries the licence on every row.

Why is misurepremiali-pnrrpnc not a collection? ANAC publishes that file as a bare header with zero rows: 43 bytes. It is left out rather than offered as an option that could only ever return nothing.

What input does the ANAC Italy Public Procurement Scraper - Tenders & Awards accept?

FieldTypeWhat it doesDefault
collections required array Which ANAC tables to pull. Tenders (CIG) is the core one: every other procurement table joins to it on the `cig` field. Each collection bills its own event, so pick only what you need. ["tenders"]
snapshot string (3 options) **Selected period** reads the per-month archives for the years below, the only way to reach history. **Latest monthly update** reads the newest incremental file ANAC published. **Full snapshot** reads the complete table (large; not published for tenders and SmartCIG, which fall back to the latest update). period
years array Years to read when the mode above is *Selected period*. Tenders go back to 2007, SmartCIG to 2011, OCDS releases to 2018. ["2025"]
months array Months to read within each year. Leave empty for all twelve. Only tenders, SmartCIG and OCDS are split by month; the other tables ignore this. ["1"]
maxItems integer Hard cap on rows written across every collection. The download stops the moment the cap is met, so a small cap costs a small transfer even on a 200 MB archive. 1000
maxItemsPerCollection integer Optional per-collection cap, so one huge table cannot eat the whole budget when several are selected. not set
searchTerms array Keep rows whose subject, supplier or buyer name contains any of these (case-insensitive substring). Example: `fotovoltaico`, `ambulanza`. not set
cigs array Keep only these tender identifiers. Works across every procurement table, which is how you assemble the full lifecycle of one contract. not set
fiscalCodes array Keep rows where any party: buyer, winner, bidder, subcontractor: carries one of these codice fiscale or partita IVA values. Punctuation and country prefixes are ignored. not set
cpvCodes array Common Procurement Vocabulary prefixes, matched from the left. `45` keeps all construction, `45112000-5` keeps just that class. not set
regions array Italian region names, matched against the ANAC regional section. Example: `LOMBARDIA`, `SICILIA`. not set
provinces array Province name or ISO code. Example: `MILANO`, `IT-MI`. not set
sectors array The main object of the contract. not set
procedureTypes array Award procedure, by ANAC code or by name. Example: `AFFIDAMENTO DIRETTO`, `PROCEDURA APERTA`, or the numeric code `24`. Read the `reference-codes` collection for the full table. not set
statuses array Record status, matched as a substring. Example: `ATTIVO`, `SCADUTO`. not set
minAmount integer Drops rows whose contract or award value is below this. Rows with no monetary field are dropped too. not set
maxAmount integer Drops rows whose contract or award value is above this. not set
dateFrom string ISO date. Filters on the row's own publication, communication or award date. not set
dateTo string ISO date, inclusive. not set
onlyPnrr boolean Keep only tenders funded by Italy's Recovery and Resilience Plan. false
onlySingleBid boolean Keep only awards that drew exactly one bidder, the standard first red flag in competition analysis. false
excludeCancelled boolean Drop tenders carrying a cancellation date or reason. false
catalogQuery string Full-text query passed to CKAN when scraping the catalogue collections (datasets, distributions). Solr syntax works. not set
catalogGroups array Restrict catalogue results to these DCAT theme groups. not set
catalogFormats array Restrict catalogue results to datasets publishing these distribution formats. not set
includeRawColumns boolean Adds a `raw` object holding every column exactly as ANAC wrote it, alongside the typed fields. Roughly doubles row size. false
includeOcdsRelease boolean Keeps the complete OCDS 1.1 release under `release`. Turn off for a flat summary row. Releases over 512 KB are dropped either way and flagged with `releaseTruncated`. true
proxyConfiguration object **Keep this on.** The ANAC portal's WAF blocks the Apify platform's own IP range with HTTP 403, so a run without a proxy returns nothing. Apify's datacenter proxy is enough: residential is not needed. {"useApifyProxy":true}
timeoutSecs integer Seconds the actor may spend fetching before it flushes and exits cleanly. Kept under the run timeout so a long run still returns what it has. 1500

How much does the ANAC Italy Public Procurement Scraper - Tenders & Awards cost?

from $4.00 per 1,000 results

Charged forWhat it isPrice each
Actor Start Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). $0.007
Catalogue record One dataset, distribution, organisation, theme, tag or reference code from the ANAC CKAN catalogue. Includes the lookup tables that resolve the numeric codes on tender rows. $0.002
Tender (CIG) One tender lot with its CIG: subject, value, procedure type, CPV, contracting authority, cost centre, region, publication and outcome dates, PNRR flag: 84 fields in all, back to 2007. $0.005
Simplified tender (SmartCIG) One low-value contract acquired through the SmartCIG route, with subject, value, contract category, procedure, authority and municipality. Back to 2011. $0.005
Award One award decision: awarded amount, discount off the base price, award criterion, bids received, admitted, excluded and invited, e-auction flag and a derived single-bid marker. $0.005
Winning operator One firm that won a CIG, with fiscal code, legal name, its role inside the consortium or joint venture and its operator type. $0.005
Bidder One firm that bid for a CIG, losing bidders included, the side of the file that lets you measure who competes against whom. $0.005
Contract milestone One execution event: contract start, contract end, acceptance testing or suspension, with its dates, reasons and outcome. $0.005
Progress report (SAL) One certified progress instalment with its amount, issue date, late flag, days of slippage and payment certificate. $0.005
Contract variation One approved variation with the legal ground claimed for it and the supplementary deed date. $0.005
Subcontract One authorised subcontract: subject, work category, amount class, CPV, and both the subcontracting and the subcontracted firm. $0.005
Economic framework line One quadro economico line splitting the contract value into works, services, supplies, design, safety and contingency amounts at a point in time. $0.005
Funding source One funding breakdown: state, regional, local, EU and private contributions, loans, own budget and asset transfers, each as its own amount. $0.005
Publication record Where and when the notice was published: register, Gazzetta Ufficiale, OJEU and regional bulletin dates, plus the invitation deadline. $0.005
Work classification One work type, SOA work category or DPCM aggregation category attached to a CIG, with its code, description and amount class. $0.004
Tender attribute One CIG-to-CUP investment-project link, or the PNRR female and youth employment quotas carried by a recovery-plan tender. $0.004
Contracting authority One of the ~48,000 registered buyers: AUSA code, fiscal code, VAT number, legal nature, address, province, in-house and state-owned flags and registry status. $0.006
Cost centre One purchasing unit inside a contracting authority, with its address, aggregator flag and the parent authority it reports to. $0.005
SOA certificate One SOA qualification certificate or one of the categories it grants, the record that says which firms may legally bid for works over EUR 150,000 and up to what value. $0.006
OCDS release One contracting process in Open Contracting Data Standard 1.1: ocid, awards, every party with its address, items with CPV classification, the CIGs of every lot, and the raw release object. Read out of multi-gigabyte bulk files. $0.009

Tiered: the lower figure is the price on a higher Apify plan. Billing and the free credit live on Apify.

How do I call the ANAC Italy Public Procurement Scraper - Tenders & Awards API?

One POST returns the dataset directly. Same shape for every scraper in the library, so swapping the slug is the only change.

POST ยท run and get results
curl -X POST "https://api.apify.com/v2/acts/parseforge~anac-italy-procurement-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "collections": [
      "tenders"
    ],
    "snapshot": "period",
    "years": [
      "2025"
    ],
    "months": [
      "1"
    ],
    "maxItems": 1000
  }'

What example inputs can I use?

Use these inputs to see how a run is configured.

input.json
{
  "collections": [
    "tenders"
  ],
  "snapshot": "period",
  "years": [
    "2025"
  ],
  "months": [
    "1"
  ],
  "maxItems": 1000
}

What do users say about the ANAC Italy Public Procurement Scraper - Tenders & Awards?

No reviews yet. Be the first.

How do I report an issue with the ANAC Italy Public Procurement Scraper - Tenders & Awards?

We build and maintain this scraper, so a problem with it comes to us. Report it on the Apify listing and the thread stays attached to the scraper where the next person can find it: open an issue.

Broken and urgent, or you would rather not post in public? Write to parseforge@protonmail.com and it reaches the people who wrote it.

What related scrapers can I use?

Run ANAC Italy Public Procurement Scraper - Tenders & Awards on Apify All scrapers