Brazil Central Bank (BCB) Financial Institutions Lookup avatar

Brazil Central Bank (BCB) Financial Institutions Lookup

Pricing

$10.00 / 1,000 matched institution records

Go to Apify Store
Brazil Central Bank (BCB) Financial Institutions Lookup

Brazil Central Bank (BCB) Financial Institutions Lookup

Check whether a company is a Banco Central do Brasil-authorized financial institution (bank, fintech/payment institution, credit union, brokerage, and more) by CNPJ or name, with authorization status and institution type. Pay only for matched records.

Pricing

$10.00 / 1,000 matched institution records

Rating

0.0

(0)

Developer

Alison Moura

Alison Moura

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Check whether a company is a Banco Central do Brasil-authorized financial institution — bank, fintech/payment institution, credit union (cooperativa de crédito), brokerage (corretora/distribuidora), consórcio administrator, virtual-asset service provider, and more — by CNPJ or by name. Get back a clean, normalized record with authorization status, institution type, and legal nature, sourced directly from BCB's own supervised-entity registry (BcBase). Pay only for matched records.

Who this is for

Anyone who needs to answer "is this company actually a regulated financial institution, and is it currently authorized?" — fintech/KYC and AML tooling verifying a counterparty isn't an unlicensed operator, payment processors doing merchant due diligence, credit-risk and lending platforms checking whether a partner bank/fintech is in good standing, or anyone using cnpj-lookup who also needs to confirm a specific CNPJ is BCB-authorized rather than just registered with Receita Federal (every CNPJ is in Receita Federal's registry; only a small, specific subset is in this one).

What you send in

{
"queries": ["18.236.120/0001-58", "Nubank", "BNDES"],
"maxResultsPerQuery": 20,
"maxConcurrency": 5
}
  • queries — a list of CNPJs (full 14-character, or the 8-character "root" identifying the company regardless of branch/establishment; punctuation optional) and/or free-text institution name fragments, one per item. A value that cleans down to exactly 8 or 14 alphanumeric characters is treated as a CNPJ and matched exactly; anything else is treated as a case-insensitive substring search against the institution's legal name, short name, and trade name.
  • maxResultsPerQuery — optional, default 20, max 50. Caps how many matched institutions a single name search can return (and therefore charge for) — a broad term like "banco" matches hundreds of entities. Does not affect CNPJ queries, which always resolve to at most one record.
  • maxConcurrency — optional, default 5, max 10.

What you get back

One dataset record per matched institution. Example (a CNPJ query for Nubank's regulated payment-institution entity):

{
"cnpj": "18236120000158",
"cnpj_formatted": "18.236.120/0001-58",
"cnpj_root": "18236120",
"bacen_id": "Z9318261",
"sisbacen_code": "40923",
"legal_name": "NU PAGAMENTOS S.A. - INSTITUIÇÃO DE PAGAMENTO",
"legal_name_plain": "NU PAGAMENTOS S A INSTITUICAO DE PAGAMENTO",
"short_name": "NU PAGAMENTOS - IP",
"trade_name": "NUBANK",
"acronym": null,
"institution_type": { "code": 41, "description": "Instituição de Pagamento" },
"legal_nature": { "code": 9, "description": "Sociedade Anônima de Capital Fechado" },
"authorization_status": {
"code": 3,
"description": "Autorizada em Atividade",
"is_currently_authorized": true
},
"public_sector": { "is_public": false, "sphere_code": null, "sphere_description": null },
"location": {
"country": "Brasil", "country_iso3": "BRA", "state": "São Paulo",
"municipality": "São Paulo", "municipality_ibge_code": "3550308"
},
"as_of_date": "2026-08-17",
"_meta": {
"source": "bcb-bcbase",
"matched_query": "18.236.120/0001-58",
"match_type": "cnpj",
"retrieved_at": "2026-08-17T14:32:10+00:00",
"data_license": "ODbL (Open Data Commons Open Database License) - Banco Central do Brasil, dadosabertos.bcb.gov.br"
}
}

A name search returns one record per matching institution — searching "Nubank" returns 3 distinct entities (the payment institution, the brokerage, and the financing company), each a separate regulated entity with its own CNPJ.

For a query that's invalid, not found, or errored, you still get a record so you can see what happened to every input — it's just not charged:

{ "query_input": "00000000000000", "query_type": "cnpj", "status": "invalid_format", "error": "invalid check digits (not a real CNPJ)" }
{ "query_input": "33.000.167/0001-01", "query_type": "cnpj", "status": "not_found" }
{ "query_input": "Zzzznonexistent", "query_type": "name", "status": "no_matches" }

Note: not_found for a CNPJ means "not in BCB's authorized-institution registry," not "invalid company" — most Brazilian companies (e.g. Petrobras) are legitimate, active CNPJs that simply aren't financial institutions BCB supervises. Use cnpj-lookup to check general company registration status instead.

What "authorized" means

authorization_status.is_currently_authorized is true only for status code 3, "Autorizada em Atividade" (authorized and currently operating) — deliberately narrower than any status merely containing the word "Autorizada." BCB's registry also uses "Autorizada sem Atividade" (authorized but not currently operating) as a distinct status, which this field correctly reports as false. The full authorization_status.code/ description is always included so you can see the exact underlying status (e.g. "Cancelada/Encerrada", "Em Liquidação Extrajudicial") regardless of how the boolean simplifies it.

Pricing

Pay-per-event: you are charged only for matched institution records — the single record resolved from an exact CNPJ match, or each institution returned by a name-fragment search. Not charged for CNPJs with no match, name searches with no matches, invalid-format queries, or lookup errors. See the Actor's Store page for the current per-event price.

Set at $0.01/record, matching cnpj-lookup's price and lower than pncp-lookup ($0.02) or ceis-lookup ($0.03). Reasoning: this Actor's real operational cost profile is closest to cnpj-lookup's — a single fast, unauthenticated, unpaginated query per CNPJ, no observed rate limiting during development, no multi-registry fan-out (unlike ceis-lookup's 3 registries per document) and no multi-call search modes or empirically-high baseline latency (unlike pncp-lookup). The narrower dataset (a specific regulatory subset, not general company data) is a value-add for the right buyer but doesn't change the cost to serve, so it doesn't justify pricing above the cheapest tier already proven on this same infrastructure pattern.

Data source, terms of use & freshness

Source: Banco Central do Brasil's own open-data portal (dadosabertos.bcb.gov.br), specifically the "Dados cadastrais de entidades supervisionadas" dataset, served live via the Olinda OData API (olinda.bcb.gov.br/olinda/servico/BcBase/versao/v2/odata/, EntidadesSupervisionadas) — the same registry BCB itself uses internally (Unicad/BCBase). No authentication required; verified live 2026-08-17 with zero auth headers on every call.

Terms of use — verified directly against the primary source, not assumed: the dataset's own page on dadosabertos.bcb.gov.br (fetched 2026-08-17) shows an explicit ODbL (Open Data Commons Open Database License) badge, and references this exact BcBase/EntidadesSupervisionadas/ Olinda API resource directly — not a generic portal-wide claim taken on faith. ODbL's own text (Open Data Commons,

opendatacommons.org/licenses/ odbl/1-0/
) explicitly states granted rights "expressly include commercial use, and do not exclude any field of endeavour." The one real obligation it imposes — a notice making any user of an output ("Produced Work") aware the content was obtained from the source database — is satisfied by the _meta.data_license field this Actor already includes on every output record; ODbL's share-alike clause applies to redistributing the database itself, not to a derived/normalized output like this Actor's records, so it doesn't apply here. This is a cleaner legal basis than either cnpj-lookup's (cleared by the absence of a resale prohibition in a third-party API's ToS) or ceis-lookup's (a general open-data-policy argument) — closer to pncp-lookup's explicit-permission case, and confirmed against the specific dataset actually used here, not the open-data portal in general.

Freshness: this Actor always queries with today's date as BCB's dataBase snapshot parameter, so results reflect BCB's most current published registry state — not a stale/cached copy. BCB itself updates the underlying registry on its own schedule (not published as a fixed interval); any of the fields here (institution status, name, etc.) can lag a real-world change by BCB's own update cycle. For anything with legal/compliance weight, treat this as a fast first-pass check, not a substitute for BCB's own official channels.

Rate limits & fair use

No published rate limit was found for this API (same situation as this developer's cnpj-lookup and pncp-lookup Actors). This Actor paces its own requests conservatively (~3 req/s ceiling) with retry/backoff, rather than a number taken from documentation. maxConcurrency (max 10) lets you tune parallelism within that ceiling.


For the Aurora project (internal)

Fourth product built per DECISIONS.md ADR-008's owner-directed expansion (alongside ceis-lookup, tse-electoral-lookup, and anvisa-products-lookup). Code, .actor/ schemas, Dockerfile, and fixtures were built in an earlier session that was interrupted by a Claude usage session limit before tests and this README were written (see BUSINESS.md's "2026-08-17" snapshot, "2 PARTIAL, paused"). This session finished the product: wrote the missing test suite, found and fixed one real bug the earlier session's code hadn't yet been run live against, and verified the data source's terms of use directly rather than trusting the _meta.data_license string already present in the code.

A real bug found and fixed during this session

The client (bcb_institutions_lookup/client.py) was passing OData $filter values to httpx via its standard params= argument, which encodes spaces as + (application/x-www-form-urlencoded convention). This API's OData parser does not decode + back into a space — it reads a + inside $filter as OData's own arithmetic-addition operator, so every real query (both CNPJ-exact and name-search) failed with

HTTP 400 {"codigo":400,"mensagem":"The types 'Edm.Boolean' and 'Edm.String' are not compatible."}
. This was invisible to the mocked unit tests (httpx.MockTransport doesn't validate OData syntax the way the real server does) and was only caught by this session's live end-to-end smoke test — exactly the kind of gap pncp-lookup's ADR-010 flagged as worth specifically checking for, not assuming away. Fixed by building the query string by hand with %20-encoded spaces (urllib.parse.urlencode(params, quote_via=urllib.parse.quote)) instead of httpx's default encoding. Covered by a dedicated regression test (tests/test_client.py::TestQuerySuccess::test_space_encoding_uses_percent20_not_plus) that inspects the actual raw query string sent, not just that a mocked 200 comes back — a mock would have passed either way, which is exactly why this bug survived the original mocked test suite undetected until a real live call was made.

What was actually tested vs. not

Tested and passing:

  • 97/97 tests (pytest, Python 3.12 venv — same reasoning as cnpj-lookup's README for why 3.12 not the VPS's default 3.10: the apify SDK needs Python ≥3.11 and this VPS has no python3.10-venv installed and no passwordless sudo). Covers CNPJ/CNPJ-root cleaning and validation (test_cnpj_utils.py), raw-record-to-output normalization against real captured fixtures for 6 distinct real institutions — Nubank's payment-institution entity, BNDES (a public/federal entity), a cancelled/closed entity, a cooperativa de crédito, and a 3-result name search (test_normalize.py), the OData client's filter-building, response parsing, retry/backoff, pacing, and error-wrapping including the space-encoding regression above (test_client.py), and the main orchestration's input coercion, dedupe, CNPJ-vs-name query routing, and per-query push/charge behavior with a mocked client (test_main.py).
  • ruff lint: clean, zero warnings.
  • apify-cli validate-schema: passes for both input_schema.json and dataset_schema.json.
  • Full live end-to-end runs against the real internet, twice, after the space-encoding fix: once via direct
    python -m bcb_institutions_lookup
    (4 queries: Nubank's CNPJ, "Nubank" name search, "BNDES" name search, and a deliberately invalid all-zeros CNPJ — result: 6 real institution records matched, 1 correctly rejected as invalid, 0 errors) and once via the official apify-cli run command (which reads .actor/actor.json exactly as the real platform would; "Itaú" name search + Nubank's CNPJ — 4 real institution records matched, 0 errors). Real data confirmed correct in both runs: exact CNPJ resolution, multi-result name search (3 distinct Nubank-group entities, 2 distinct BNDES-group entities), and clean invalid-format rejection.
  • Terms of use verified directly against the primary source (the specific dataset page on dadosabertos.bcb.gov.br, not a generic portal claim) and against ODbL's own published license text — see "Data source, terms of use & freshness" above.

Not tested / could not verify locally:

  • Real pay-per-event charging behavior: running locally, the Apify SDK correctly no-ops with the log line
    "Ignored attempt to charge for an event - the Actor does not use the pay-per-event pricing"
    (no platform pricing config exists outside a real platform run) — same situation as every other Aurora product before its own deployment. The charging code path is exercised (called on every matched record; the event_charge_limit_reached stop-early behavior is covered by mocked unit tests) but actual billing can only be confirmed after deploying and monetizing on the real platform.
  • Docker build: this VPS has no Docker installed (no root/sudo available), so Dockerfile was never built into an image here. It follows the same template already proven to build successfully on Apify's infrastructure for cnpj-lookup and pncp-lookup (
    FROM apify/actor-python:3.13
    , byte-compile step,
    CMD ["python", "-m", "bcb_institutions_lookup"]
    ).
  • No real paid usage, no Apify Store listing yet — not deployed anywhere outside this repo and this VPS.
  • The "all retries exhausted" / BcbRequestError path for a genuinely unreachable API is exercised by mocked unit tests only — there was no way to make the real live API fail on demand during this session (it was, in fact, fully reachable and working throughout).

Deployment

Same proven pattern as cnpj-lookup (ADR-006/007) and pncp-lookup (ADR-011) — no special access/key needed, unlike ceis-lookup's Portal da Transparência key requirement. BCB's Olinda API is open, like CNPJ's and PNCP's sources: no signup, no application, no auth header. Account-level prerequisites (payout billing info, public profile, Store Terms acceptance) already carried over from the cnpj-lookup deployment and should need no further owner action.

Remaining steps, all executable without additional owner input once run:

  1. cd products/bcb-institutions-lookup && npx apify-cli push — build on Apify's infrastructure (same Dockerfile pattern already proven twice).
  2. npx apify-cli call -i '{"queries": ["18.236.120/0001-58", "Nubank"]}' -o — real end-to-end smoke test from Apify's platform (different egress IP than this VPS; the space-encoding bug above was already caught and fixed from this VPS, but re-confirming from Apify's own network before monetizing costs nothing and matches the rigor pncp-lookup applied at this same step).
  3. Set pay-per-event pricing (pricingInfos, event institution-record at $0.01, per .actor/pay_per_event.json) and publish (
    isPublic: true
    , categories Business + Lead generation or similar) via the Apify REST API PUT /v2/acts/{actorId} — the exact call pattern already proven twice (cnpj-lookup ADR-007, pncp-lookup ADR-011).
  4. Optional: generate and upload a Store logo (non-blocking, same as pncp-lookup's outstanding optional step).
  5. Report real results (impressions, runs, revenue) into BUSINESS.md once real usage exists — do not fabricate numbers before they exist.