Brazil CNPJ Sanctions — CEIS, CNEP, CEPIM and Leniency avatar

Brazil CNPJ Sanctions — CEIS, CNEP, CEPIM and Leniency

Pricing

$2.00 / 1,000 cnpj checkeds

Go to Apify Store
Brazil CNPJ Sanctions — CEIS, CNEP, CEPIM and Leniency

Brazil CNPJ Sanctions — CEIS, CNEP, CEPIM and Leniency

Screen Brazilian legal entities against four official CGU public downloads, with checksum validation and daily caching.

Pricing

$2.00 / 1,000 cnpj checkeds

Rating

0.0

(0)

Developer

Kadev Code

Kadev Code

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Brazil CNPJ Sanctions Screening

Screen Brazilian companies against the official CEIS, CNEP, CEPIM and Acordos de Leniência public downloads from the CGU Portal da Transparência. This Actor accepts a batch of CNPJs and produces one structured dataset item for each distinct normalized identifier. It requires no Portal API key and runs with Python 3.12 and the Apify SDK, without a browser.

This is an informational lookup and does not replace an official certificate (consulta informativa; não substitui certidão oficial). Review source records and obtain the appropriate official certificate before making a procurement or legal decision. A list occurrence is not a risk score or an automatic rejection rule.

Input

{"cnpjs": ["00.000.000/0001-91", "11.222.333/0001-81"]}

Provide between 1 and 1,000 strings. Standard or partial masks (for example, 00.000.000/000191), unformatted numeric CNPJs, and alphanumeric CNPJs are supported. The two check digits are validated using the Receita Federal algorithm. Validation checks the identifier's syntax and checksum, not its registration or operating status. Duplicate normalized identifiers are delivered and billed once. Missing local input uses the schema's default example, a public company CNPJ. An empty list or malformed top-level input produces a free input-error item.

Output and interpretation

The following is an illustrative shape, not a live statement about this company:

{
"cnpj": "00000000000191",
"companyName": null,
"validCnpj": true,
"sanctioned": false,
"activeSanction": false,
"lists": [],
"records": [],
"stale": false,
"staleSources": [],
"partialData": false,
"warnings": [],
"sourceQuality": {},
"datasetDate": {
"CEIS": "2026-10-21",
"CNEP": "2026-10-21",
"CEPIM": "2026-10-21",
"Acordos de Leniência": "2026-10-22"
},
"error": null
}

Each matching record contains list, cnpj (the source identifier), matchType, sanctionType, sanctioningBody, sanctionScope (ABRANGÊNCIA DA SANÇÃO when published), startDate, endDate, dateUnknown, active and legalBasis. Matching includes every establishment sharing the first eight CNPJ characters: matchType: "exact" matches the requested identifier; "sameRoot" identifies another branch or headquarters in that company root. Review the source's scope before deciding whether a sanction legally applies to a specific establishment. Dates use ISO format; absent or invalid dates and unavailable fields are null. CEPIM does not publish start/end dates in this download, so both remain null. For leniency, legalBasis contains the published agreement terms; for CEPIM, it contains the reason for the impediment.

Every record has the same 36 keys. The table below includes all fields. Text is trimmed and CPF patterns are redacted, including in company names and remarks. Empty or unavailable fields are null; dates are ISO YYYY-MM-DD. Invalid publication/information/transit dates are also null and do not change the activity calculation, which uses only the original start/end bounds.

FieldType (nullable unless stated)Source / meaning
liststring, requiredOfficial list name
cnpjstring, requiredValidated source CNPJ
matchTypestring, requiredexact or sameRoot
sanctionTypestringCEIS/CNEP CATEGORIA DA SANÇÃO; source category for CEPIM/leniency
sanctioningBodystringÓRGÃO SANCIONADOR; CEPIM ÓRGÃO CONCEDENTE
sanctionScopestringCEIS/CNEP ABRAGÊNCIA DA SANÇÃO (published spelling); ABRANGÊNCIA is also supported
startDate, endDatedate stringSanction dates or leniency agreement start/end
dateUnknownboolean, requiredA nonempty start/end bound could not be parsed
activeboolean, requiredActivity on the screening date, using start/end bounds
legalBasisstringFUNDAMENTAÇÃO LEGAL, CEPIM reason, or leniency terms
registrystringCEIS/CNEP CADASTRO
sanctionIdstringCEIS/CNEP CÓDIGO DA SANÇÃO
personTypestringCEIS/CNEP TIPO DE PESSOA (company rows only)
sanctionedNamestringCEIS/CNEP NOME DO SANCIONADO
reportedNamestringCEIS/CNEP NOME INFORMADO PELO ÓRGÃO SANCIONADOR
companyNamestringRAZÃO SOCIAL - CADASTRO RECEITA; CEPIM NOME ENTIDADE
tradeNamestringNOME FANTASIA - CADASTRO RECEITA, including the leniency en-dash spelling
sanctionedUfstringAlways null in the verified downloads: no company-state column is published
sanctioningBodyUfstringCEIS/CNEP UF ÓRGÃO SANCIONADOR; this is the authority's state
sanctioningBodySpherestringCEIS/CNEP ESFERA ÓRGÃO SANCIONADOR
processNumberstringCEIS/CNEP/leniency NÚMERO DO PROCESSO
publicationDatedate stringCEIS/CNEP DATA PUBLICAÇÃO
publicationSourcestringCEIS/CNEP PUBLICAÇÃO
publicationDetailsstringCEIS/CNEP DETALHAMENTO DO MEIO DE PUBLICAÇÃO
transitDatedate stringCEIS/CNEP DATA DO TRÂNSITO EM JULGADO
fineValuenumberCNEP VALOR DA MULTA in BRL; decimal comma/grouping dots become a JSON number; invalid text becomes null
informationDatedate stringCEIS/CNEP DATA ORIGEM INFORMAÇÃO; leniency DATA DA INFORMAÇÃO
informationSourcestringCEIS/CNEP ORIGEM INFORMAÇÕES
remarksstringCEIS/CNEP OBSERVAÇÕES
transferAgreementNumberstringCEPIM NÚMERO CONVÊNIO
impedimentReasonstringCEPIM MOTIVO DO IMPEDIMENTO; also in legalBasis
agreementIdstringLeniency ID DO ACORDO
agreementStatusstringLeniency SITUAÇÃO DO ACORDO DE LENIÊNICA (published spelling)
agreementTermsstringLeniency TERMOS DO ACORDO; also in legalBasis
agreementEffectsarrayLeniency Efeitos.csv rows joined by agreement ID; each has nullable effect (EFEITO DO ACORDO DE LENIENCIA) and details (COMPLEMENTO)

Identifiers and process/agreement numbers remain strings to preserve leading zeros. There is no separate decision-date column in the checked files; transitDate is the published final-decision date. Leniency's responsible body is in sanctioningBody; its dates are startDate and endDate. An absent effect file or an agreement without matching effects produces agreementEffects:null. Other lists have agreementEffects:null as well.

At item level, companyName comes from the first exact record, or the first record if there is no exact match. Within that selected record, the Actor uses companyName, then sanctionedName, then reportedName. It returns null if that record has no name or there are no records. Billing-status items retain the delivered item's name. The Actor uses only the names already present in CGU downloads; it makes no Receita or Portal API lookup.

For example, a synthetic CNEP match can contain this record (all values below are invented test data, not a real sanctions finding):

{
"list": "CNEP",
"cnpj": "00000000000191",
"matchType": "exact",
"sanctionType": "Multa",
"sanctioningBody": "Example authority",
"sanctionScope": "Nacional",
"startDate": "2026-01-01",
"endDate": "2026-12-31",
"dateUnknown": false,
"active": true,
"legalBasis": "Synthetic legal basis",
"registry": "CNEP",
"sanctionId": "00012",
"personType": "J",
"sanctionedName": "Example company",
"reportedName": "Example company as reported",
"companyName": "Example company Ltda",
"tradeName": "Example trade name",
"sanctionedUf": null,
"sanctioningBodyUf": "DF",
"sanctioningBodySphere": "Federal",
"processNumber": "001/2026",
"publicationDate": "2026-01-02",
"publicationSource": "DOU",
"publicationDetails": "Section 1",
"transitDate": "2026-01-03",
"fineValue": 1234567.89,
"informationDate": "2026-10-22",
"informationSource": "CGU",
"remarks": "Synthetic observation",
"transferAgreementNumber": null,
"impedimentReason": null,
"agreementId": null,
"agreementStatus": null,
"agreementTerms": null,
"agreementEffects": null
}

The containing item's companyName would be "Example company Ltda" if this were its first exact record. A leniency record can instead have "agreementEffects":[{"effect":"Synthetic effect","details":null}].

sanctioned and activeSanction mean at least one active matching record. Historical records remain visible with active:false. Activity is evaluated on the run's UTC date, including the start/end dates themselves, even for cached records. Missing bounds are open-ended; an invalid date sets dateUnknown:true and conservatively keeps the record active. This date-based indicator includes leniency and CEPIM occurrences and is not a legal enforceability decision. A successful no-match result has all four dataset dates and error:null. On source/cache failure the indicators are null (unknown), with an explicit error and no screening fee. Never interpret an error as clearance.

Every output item includes partialData and warnings. If any used base has discarded malformed rows without a recoverable CNPJ within the 1% tolerance, partialData:true applies to every screening using that base, including matches and no matches. warnings contains one readable notice per affected base:

{
"code": "SOURCE_PARTIAL",
"source": "CEPIM",
"rejectedRows": 1,
"message": "CEPIM: 1 malformed row(s) discarded; at least one has no recoverable CNPJ, so occurrences may be missing."
}

rejectedRows counts all malformed rows discarded in that base, including those with known CNPJs; it is not a count of unidentified rows or missing sanctions. Clean bases produce partialData:false and warnings:[]. The flag uses the snapshot actually screened, including daily cache and stale fallback; it does not describe a failed refresh that was replaced by another snapshot. Status items of type:"billingStatus" inherit these fields from the delivered screening. Input/source errors and unprocessed items that use no bases have partialData:false and warnings:[]; that flag alone does not establish a successful screening. Always check error, partialData and stale alongside the sanction indicators.

Official sources and freshness

The following official pages and their dated download routes were checked on 2026-10-22. The Actor reads the page's embedded arquivos.push date metadata and uses the latest published date, rather than guessing today's archive name.

ListOfficial discovery pageVerified download route
CEISCEIS downloads20261022
CNEPCNEP downloads20261022
CEPIMCEPIM downloads20261021
LeniencyAgreement downloads20261022

These routes redirected to https://dadosabertos-download.cgu.gov.br/PortalDaTransparencia/saida/<slug>/<YYYYMMDD>_<name>.zip. Names were CEIS, CNEP, CEPIM and AcordosLeniencia, respectively. Agreements contain both an Acordos.csv and an auxiliary Efeitos.csv; effects are joined to validated company agreements by ID. Windows-1252 and UTF-8 CSV files are supported.

Each base is normalized once when its published date changes and retained as compressed JSON in the named key-value store br-cnpj-sanctions-cache-v3. This store belongs to the user's Apify account: it is reused across that account's sequential runs, not shared globally between customers. Version 3 uses new cache keys for enriched records, with a root index and row-quality metadata; v1/v2 data is not reused because it lacks the complete fields. The first run after this upgrade downloads all four bases again. Subsequent sequential runs reuse snapshots during the UTC day. The next day checks publication metadata and downloads a ZIP only if the source date changed. There is no download per CNPJ. Dates describe the publisher's snapshot, not the time of this run; weekends can legitimately retain older dates. If refreshing a base fails, a validated prior snapshot can be used for at most seven days after its datasetDate (and last successful check). The item exposes stale:true, staleSources and the unchanged datasetDate for each list. Failed refreshes never advance that date or the successful-check timestamp. An accepted fallback screening uses the normal event price. Expired, corrupt, future-dated or incompatible cache cannot authorize a result: return an error without a fee if any source lacks an acceptable snapshot. Concurrent cold runs may duplicate a refresh because the key-value store does not provide a distributed lock; serialize scheduled runs when avoiding that duplication is essential.

Privacy, limits and errors

Only validated company identifiers enter the normalized cache. Individual rows are excluded; company names and the documented fields are retained through an explicit column allowlist. Raw rows and unrelated columns are not retained. CPF patterns in all text fields are redacted. An invalid CPF-shaped input is returned as cnpj: null, without echoing the supplied personal identifier. Raw downloads remain in memory only. The dataset contains the requested company screening results and follows your Apify storage retention settings.

Requests have a 15-second connection timeout, a 40-second idle-operation timeout, and a 60-second global deadline covering redirects, streaming, all retries and backoff. Loading all four bases has an additional 240-second global deadline. If that deadline cancels refresh, a cache-only recovery validates all four snapshots and returns them with stale metadata; no further HTTP is attempted. Recovery reads the account's KVS after the refresh deadline. If any snapshot is unusable, the result remains SOURCE_TIMEOUT and is not charged. Up to three attempts use exponential backoff on transient failures. ZIPs are limited to 32 MiB compressed and 160 MiB expanded; normalized cache is capped at 64 MiB per base. The Actor checks headers and rejects empty or changed schemas. Malformed rows are discarded and counted; more than 1% rejects the entire base with SOURCE_TOO_MANY_BAD_ROWS. sourceQuality reports total, rejected and invalid-date row counts, unknownIdentityRows (whether any discarded row lacks a recoverable CNPJ), and uncertainRootCount. A discarded row with a known company root prevents screening that root (SOURCE_INCOMPLETE_ROWS). An unidentified discarded row consumes the same 1% allowance and does not block every company; it sets partialData:true and a SOURCE_PARTIAL warning for every screening using the affected base. Tolerated rejects mean occurrences may be missing, so sanctioned:false with partialData:true is a partial lookup and does not establish absence of sanctions. These warnings do not change error or the normal screening fee. If all rejected rows have recoverable CNPJs, partialData remains false; known affected roots still return SOURCE_INCOMPLETE_ROWS and are not charged. Above 1%, refresh fails and uses a validated snapshot up to seven days old before returning an error. Cache encoding above 64 MiB follows that same fallback rule. Error items are not charged. The internal uncertainRoots array remains in the account cache to identify affected queries, but is omitted from dataset items: aggregate counts explain source quality without repeating unrelated company identifiers in every result. Invalid dates become null, are counted separately and preserve the record. Common errors include INVALID_CNPJ, SOURCE_UNAVAILABLE, SOURCE_SCHEMA_CHANGED, SOURCE_EMPTY and SOURCE_TIMEOUT and CACHE_OR_SOURCE_UNAVAILABLE. Permission to read/write the account's named cache is needed. The platform's limited permissions mode was not tested by this enrichment change; see verification.md for that launch prerequisite. A permissions failure returns an error without a fee. Foreign entities without a valid Brazilian CNPJ cannot be matched. The Actor definition defaults to 256 MiB, with a 256–512 MiB allocation range. Configure a 300-second run timeout in Console when preparing the unpublished Actor.

Pricing and SDK integration

Proposed pricing is $0.002 per cnpj-checked event ($2 per 1,000 complete, valid screenings). A completed no-match lookup is a delivered screening result. Tolerated partial-data screenings use the same fee, including no-match results; SOURCE_PARTIAL is a warning, not a billing error. Invalid inputs, unavailable/empty sources and failed deliveries are not billed; there is no startup event. The Actor checks the SDK's remaining event allowance before loading data and before each valid screening, pushes the result, then calls Actor.charge(event_name="cnpj-checked", count=1, idempotency_key=cnpj). The normalized CNPJ prevents duplicate billing inside a run. On a charge failure, the delivered result remains, followed by a type:"billingStatus" item with the normalized cnpj, validCnpj:true, CHARGE_FAILED_AFTER_DELIVERY and chargeConfirmed:false (confirmation was unavailable; this does not assert a refund). Further valid CNPJs receive NOT_PROCESSED_CHARGING_FAILURE errors. Spending limits similarly produce NOT_PROCESSED_SPENDING_LIMIT items. Status/error items generate no events. Consumers should branch on type:"billingStatus": it reports billing state for the preceding screening and does not contain screening records. Configure the event in Apify Console before enabling monetization; the repository's pricing document is a proposal, not a publication action.

The current API was verified against the official Actor.charge reference, ChargingManager reference and ChargeResult reference, and exercised with pinned SDK 4.1.0. The code uses the result's event_charge_limit_reached attribute and calculate_max_event_charge_count_within_limit, which returns None when unlimited. See .actor/pricing.md for current market comparisons and cost assumptions.

Local development and verification

Create a Python 3.12 virtual environment and install requirements-dev.txt. From the repository root, with that environment activated:

python -m pytest actors/br-cnpj-sanctions/tests -q
python actors/br-cnpj-sanctions/tests/smoke.py

Tests use local synthetic CSV fixtures and mocked HTTP; external socket connections are blocked (Windows asyncio's internal loopback wake-up sockets are allowed). The smoke script runs the real main() and SDK with default input and local dataset/KVS storage, replacing only official HTTP responses with synthetic fixtures. It prints a clearly labelled synthetic output item and incurs no charge. Its ignored .local-smoke directory can be inspected after execution. For a live local run, change into this Actor directory and run python -m src; that command accesses official public downloads. No cloud deployment, publication, real paid event, or Docker build is implied by local verification.