ANAC Italy Public Procurement Scraper - Tenders & Awards
Pricing
Pay per event
ANAC Italy Public Procurement Scraper - Tenders & Awards
Italian public tenders (CIG), awards, bidders, subcontracts, contract lifecycle, 48k contracting authorities, SOA certificates and OCDS releases from ANAC open data.
Pricing
Pay per event
Rating
0.0
(0)
Developer
ParseForge
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
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
awardstable 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.
Pricing
Pay-per-event. You are billed per row written, plus a $0.007 run-start fee. Filtered-out rows cost nothing, and neither do the bytes streamed past them.
| Event | Price | Fires for |
|---|---|---|
| Run start | $0.007 | Once per run |
| Tender (CIG) | $0.005 | tenders |
| Simplified tender (SmartCIG) | $0.005 | smart-tenders |
| Award | $0.005 | awards |
| Winning operator | $0.005 | winners |
| Bidder | $0.005 | participants |
| Contract milestone | $0.005 | contract-start, contract-end, testing, suspensions |
| Progress report (SAL) | $0.005 | progress-reports |
| Contract variation | $0.005 | variants |
| Subcontract | $0.005 | subcontracts |
| Economic framework line | $0.005 | economic-framework |
| Funding source | $0.005 | funding-sources |
| Publication record | $0.005 | publications |
| Cost centre | $0.005 | cost-centres |
| Contracting authority | $0.006 | contracting-authorities |
| SOA certificate | $0.006 | soa-certificates, soa-categories |
| Work classification | $0.004 | work-types, work-categories, dpcm-categories |
| Tender attribute | $0.004 | cup-links, pnrr-indicators |
| Catalogue record | $0.002 | datasets, resources, organizations, groups, tags, reference-codes |
| OCDS release | $0.009 | ocds-releases |
The run-start fee is exactly one event: maxMemoryMbytes is pinned to 1024 in actor.json, and Apify bills one start event per GB with a minimum of one.
| Rows collected | Tenders | OCDS releases | Catalogue |
|---|---|---|---|
| 100 | $0.51 | $0.91 | $0.21 |
| 1,000 | $5.01 | $9.01 | $2.01 |
| 10,000 | $50.01 | $90.01 | $20.01 |
Measured platform cost for comparison: a 1,000-row tender run consumed $0.0054 of Apify compute, storage and transfer; a 600-release OCDS run, which streams for five minutes, consumed $0.0147.
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
- Pick your Collections. Start with
tenders. - Choose Which files to read — Selected period plus a Year and Month for history, or Latest monthly update for the freshest delta.
- Narrow with CPV, region, amount or keywords if you want.
- Set Max rows for a hard ceiling on cost.
- 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.
Related actors
- European TED Tenders Scraper — EU-wide tender notices from Tenders Electronic Daily
- GAO Bid Protest Docket Scraper — US federal bid protests and decisions
- Semantic Scholar Scraper — research literature with citation graphs
