ANAC Italy Public Procurement Scraper - Tenders & Awards avatar

ANAC Italy Public Procurement Scraper - Tenders & Awards

Pricing

Pay per event

Go to Apify Store
ANAC Italy Public Procurement Scraper - Tenders & Awards

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

ParseForge

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

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 itWhat they pull from ANAC
Procurement intelligence & bid platformsLive tender feed with CPV, value, buyer and deadline — the input to a bid-alert product
Anti-corruption researchers & journalistsSingle-bid awards, zero-discount awards, contract variations and subcontract chains
B2B sales & lead generation48,000 contracting authorities with fiscal codes and addresses; which firms win what, from whom
Credit risk & supplier due diligenceA company's full award history, its subcontracting network and its SOA qualification classes
Construction & works contractorsWorks tenders by SOA category and amount class, filtered by region and CPV
Public-spending analysts & academicsPNRR-funded contracts, funding-source breakdowns, progress instalments and cost overruns
Open-contracting toolchainsOCDS 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

CollectionWhat one row isCoverage
tendersA tender lot with its CIG, 84 fieldsMonthly, 2007 → today
smart-tendersA SmartCIG low-value contractMonthly, 2011 → today
awardsAward decision: amount, discount, bid countsFull table + monthly deltas
winnersA firm that won a CIGFull table + monthly deltas
participantsA firm that bid, losers includedFull table + monthly deltas
contract-startSignature, enforceability, effective startFull table + monthly deltas
contract-endCompletion, early termination, extensionsFull table + monthly deltas
testingAcceptance testing, reserves, litigation valueFull table + monthly deltas
suspensionsSuspension with reason and resumption dateFull table + monthly deltas
progress-reportsOne SAL instalment with amount and slippageFull table + monthly deltas
variantsAn approved variation and its legal groundFull table + monthly deltas
subcontractsSubject, category, and both firmsFull table + monthly deltas
economic-frameworkValue split into works/services/supplies/designFull table + monthly deltas
funding-sourcesState, regional, local, EU, private, loansFull table + monthly deltas
publicationsRegister, GURI, OJEU, regional bulletin datesFull table + monthly deltas
work-typesType of work under a CIGFull table + monthly deltas
work-categoriesSOA category (OG/OS) and amount classFull table + monthly deltas
dpcm-categoriesDPCM aggregation category and derogationFull table + monthly deltas
contracting-authoritiesA registered buyer48,040 rows
cost-centresA purchasing unit inside a buyer158,645 rows
cup-linksCIG → CUP investment-project link7,167,369 rows
pnrr-indicatorsRecovery-plan female and youth quotas381,833 rows
soa-certificatesA SOA qualification certificate472,916 rows
soa-categoriesA category and class the certificate grants1,774,956 rows
ocds-releasesAn OCDS 1.1 contracting processMonthly, 2018 → today
datasetsA CKAN dataset with DCAT-AP_IT metadata70 rows
resourcesA distribution with its direct URL and size1,703 rows
organizationsThe publishing organisation1 row
groupsA DCAT theme group13 rows
tagsA tag or controlled-vocabulary termTags + 6 vocabularies
reference-codesA procedure, delivery mode, SmartCIG type or licence4 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 ActorEvery ANAC table, not just the tender list. Awards, bidders, subcontracts, lifecycle, buyers, SOA and OCDS.
The bidders, not just the winnersparticipants carries the firms that lost, which is the only way to measure who competes against whom.
Streaming with early abort20,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 billingKeyword, CIG, fiscal code, CPV, region, province, sector, procedure, amount, date, PNRR and single-bid, all applied while the file streams.
Typed, not raw stringsAmounts as numbers, dates as ISO 8601, flag_* columns as real booleans, with English aliases on top of ANAC's Italian names.
History back to 2007Every month of every year, picked with a year and month selector rather than a URL you have to guess.
No login, no API keyEvery 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 existColumns 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.

FeatureParseForge (this)ayrtondavoli97prompticafortuitous_piratemonkey.d.scrapingapexforge
Collections311 (tenders)1 (tenders)13 (tenders, awards, suppliers)1 (tenders)
Losing biddersYesNoNoNoNoNo
Contract lifecycle (SAL, variations, suspensions)YesNoNoNoNoNo
SubcontractsYesNoNoNoNoNo
Contracting-authority registry48,040NoNoNoNoNo
SOA qualification certificatesYesNoNoNoNoNo
OCDS 1.1 outputYesNoNoNoNoNo
History2007 →Not statedNot statedNot stated2007 →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

SettingWhat it does
CollectionsWhich of the 31 tables to pull. Each bills its own per-row event.
Which files to readSelected 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 / MonthsWhich 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 collectionHard caps. The download stops the moment the cap is met.
KeywordsSubstring match on subject, supplier and buyer names.
CIG codesPin to specific tenders. Works across every procurement table — this is how you assemble one contract's lifecycle.
Fiscal codes / VAT numbersMatch any party: buyer, winner, bidder, subcontractor. Punctuation and country prefixes ignored.
CPV codesPrefix match. 45 keeps all construction; 45112000-5 keeps just that class.
Regions / ProvincesLOMBARDIA, SICILIA; MILANO or IT-MI.
Contract sectorWorks, services or supplies.
Procedure typesBy name (AFFIDAMENTO DIRETTO) or by ANAC code (24). Run reference-codes for the full table.
StatusSubstring match, including the award outcome. AGGIUDICATA, SCADUTO.
Min / Max amountOn the contract or award value, in EUR.
Date from / toOn the row's own publication, communication or award date.
Only PNRR / PNCRecovery-plan contracts only.
Only single-bid awardsAwards that drew exactly one bidder. awards only — nothing else carries a bid count.
Exclude cancelled recordsDrops outcomes marked annulled or revoked.
Catalogue search / themes / formatsCKAN full-text and facet filters, for the datasets and resources collections.
Include untouched source columnsAdds a raw object with every column exactly as ANAC wrote it. Roughly doubles row size.
Include the full OCDS releaseKeeps the complete release object. On by default; dropped automatically below 512 MB of run memory.
ProxyOn 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.

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.

EventPriceFires for
Run start$0.007Once per run
Tender (CIG)$0.005tenders
Simplified tender (SmartCIG)$0.005smart-tenders
Award$0.005awards
Winning operator$0.005winners
Bidder$0.005participants
Contract milestone$0.005contract-start, contract-end, testing, suspensions
Progress report (SAL)$0.005progress-reports
Contract variation$0.005variants
Subcontract$0.005subcontracts
Economic framework line$0.005economic-framework
Funding source$0.005funding-sources
Publication record$0.005publications
Cost centre$0.005cost-centres
Contracting authority$0.006contracting-authorities
SOA certificate$0.006soa-certificates, soa-categories
Work classification$0.004work-types, work-categories, dpcm-categories
Tender attribute$0.004cup-links, pnrr-indicators
Catalogue record$0.002datasets, resources, organizations, groups, tags, reference-codes
OCDS release$0.009ocds-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 collectedTendersOCDS releasesCatalogue
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

  1. Pick your Collections. Start with tenders.
  2. Choose Which files to readSelected 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.