Brazil Central Bank (BCB) Financial Institutions Lookup
Pricing
$10.00 / 1,000 matched institution records
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
Maintained by CommunityActor 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/_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."}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 ascnpj-lookup's README for why 3.12 not the VPS's default 3.10: theapifySDK needs Python ≥3.11 and this VPS has nopython3.10-venvinstalled 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). rufflint: clean, zero warnings.apify-cli validate-schema: passes for bothinput_schema.jsonanddataset_schema.json.- Full live end-to-end runs against the real internet, twice, after
the space-encoding fix: once via direct (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 officialpython -m bcb_institutions_lookup
apify-cli runcommand (which reads.actor/actor.jsonexactly 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 (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"Ignored attempt to charge for an event - the Actor does not use the pay-per-event pricing"
event_charge_limit_reachedstop-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
Dockerfilewas never built into an image here. It follows the same template already proven to build successfully on Apify's infrastructure forcnpj-lookupandpncp-lookup(, byte-compile step,FROM apify/actor-python:3.13).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" /
BcbRequestErrorpath 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:
cd products/bcb-institutions-lookup && npx apify-cli push— build on Apify's infrastructure (same Dockerfile pattern already proven twice).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 rigorpncp-lookupapplied at this same step).- Set pay-per-event pricing (
pricingInfos, eventinstitution-recordat $0.01, per.actor/pay_per_event.json) and publish (, categories Business + Lead generation or similar) via the Apify REST APIisPublic: truePUT /v2/acts/{actorId}— the exact call pattern already proven twice (cnpj-lookupADR-007,pncp-lookupADR-011). - Optional: generate and upload a Store logo (non-blocking, same as
pncp-lookup's outstanding optional step). - Report real results (impressions, runs, revenue) into
BUSINESS.mdonce real usage exists — do not fabricate numbers before they exist.