# Brazil Electoral Candidate Lookup - TSE (Batch) (`jgoia/tse-electoral-lookup`) Actor

Batch-search Brazil's official TSE electoral registry for the 2024 municipal elections: candidate profile (party, coligation, office, election result) plus declared assets (bens declarados), by candidate name. Charged per matched candidate record.

- **URL**: https://apify.com/jgoia/tse-electoral-lookup.md
- **Developed by:** [Alison Moura](https://apify.com/jgoia) (community)
- **Categories:** News, Lead generation
- **Stats:** 2 total users, 1 monthly users, 33.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$20.00 / 1,000 matched candidate record returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Brazil Electoral Candidate Lookup - TSE (Batch)

Batch-search Brazil's official electoral court (TSE) open-data registry for
the **2024 municipal elections**: candidate profile (party, coligation,
office, election result across every round) plus **declared assets** (bens
declarados), by candidate name. Get back one clean, normalized JSON record
per matched candidate, ready for a PEP-screening/compliance check,
journalism/research pipeline, or civic-transparency tool.

### Who this is for

Compliance and KYC/AML teams doing politically-exposed-person (PEP)
screening, journalists and researchers studying candidates' declared
wealth or election outcomes, civic-tech and transparency projects, or
anyone using [`cnpj-lookup`](https://apify.com/jgoia/cnpj-lookup) or
[`ceis-lookup`](https://apify.com/jgoia/ceis-lookup) who also needs to
check whether a person has run for public office in Brazil, what they
declared owning at the time, and how they did.

### What you send in

```json
{
  "candidateNames": ["RICARDO NUNES", "VERA FRANÇA"],
  "uf": "SP",
  "cargo": "PREFEITO",
  "includeAssets": true,
  "maxResultsPerName": 10
}
```

- `candidateNames` - list of names to search for (full legal name or
  ballot/urna name). Matching is **substring, case-insensitive, and
  accent-insensitive** against both the candidate's full legal name and
  their ballot name - `"franca"` matches `"VERA LÚCIA SANTOS DE FRANÇA"`.
- `uf` - optional 2-letter state code (e.g. `SP`, `RJ`, `MG`) applied to
  every name in this run. Strongly recommended: restricts the search to
  one state's file instead of scanning all 26 (Distrito Federal has no
  municipal elections and isn't in this dataset - see below), which is
  faster. Omit to search nationwide.
- `cargo` - optional office filter: `PREFEITO` (mayor), `VICE-PREFEITO`, or
  `VEREADOR` (city councillor) - the only three offices in a municipal
  election.
- `includeAssets` - default `true`. Whether to join each matched
  candidate's declared-assets records into the output.
- `maxResultsPerName` - cap on matches returned per name query (default 10,
  max 50), to bound output for common names like "SILVA".

There is **no CPF/CNPJ search**. See "Personal data & intended use" below
for why: TSE itself does not disclose candidate CPFs in this dataset.

### What you get back

One record per matched candidate. Real example (São Paulo's mayor,
re-elected 2024 - a public official's public candidacy record, trimmed
here to 2 of his 32 declared assets):

```json
{
  "status": "matched",
  "query_name": "RICARDO NUNES",
  "sq_candidato": "250002098117",
  "nr_candidato": "15",
  "nome_completo": "RICARDO LUIS REIS NUNES",
  "nome_urna": "RICARDO NUNES",
  "cpf": null,
  "cpf_note": "Not disclosed by TSE for this dataset (Resolução TSE 23.609/2019 art.33 §2º, as amended by Resolução 23.729/2024) - see 'Personal data & intended use'.",
  "cargo": "PREFEITO",
  "uf": "SP",
  "municipio": "SÃO PAULO",
  "partido": { "sigla": "MDB", "nome": "MOVIMENTO DEMOCRÁTICO BRASILEIRO", "numero": 15 },
  "coligacao": { "nome": "CAMINHO SEGURO PRA SÃO PAULO", "composicao": "PP / MDB / PL / PSD / ...", "tipo_agremiacao": "COLIGAÇÃO" },
  "nascimento": { "data": "13/11/1967", "uf": "SP" },
  "genero": "MASCULINO", "raca_cor": "BRANCA", "grau_instrucao": "SUPERIOR INCOMPLETO",
  "estado_civil": "CASADO(A)", "ocupacao": "PREFEITO",
  "eleicao": { "ano": 2024, "descricao": "Eleições Municipais 2024" },
  "rounds": [
    { "turno": 1, "data_eleicao": "06/10/2024", "situacao_totalizacao": "2º TURNO" },
    { "turno": 2, "data_eleicao": "27/10/2024", "situacao_totalizacao": "ELEITO" }
  ],
  "situacao_final": "ELEITO",
  "situacao_candidatura": "DEFERIDO",
  "processo_numero": "06007550320246260001",
  "despesa_max_campanha_brl": 26910445.8,
  "reeleicao": true,
  "bens_declarados": [
    { "tipo": "Apartamento", "descricao": "APARTAMENTO CIDADE DUTRA", "valor_brl": 605000.0, "atualizado_em": "07/07/2026" },
    { "tipo": "Terreno", "descricao": "TERRENO EM CAMPINAS-SP", "valor_brl": 390000.0, "atualizado_em": "07/07/2026" }
  ],
  "bens_total_brl": 4843350.91,
  "bens_count": 32
}
```

A name that matches zero candidates still gets a record, so you can see
what happened to every query - it's just not charged:

```json
{ "query_name": "NOME QUE NAO EXISTE XYZ", "status": "no_match" }
```

### Personal data & intended use

This is **legally public data**: Brazilian electoral law (and TSE's own
regulations) require candidate registration data and declared-asset
disclosures to be published, precisely so voters and oversight bodies can
scrutinize people who have chosen to run for public office. It is not
scraped, leaked, or repurposed private data - it's an official transparency
mechanism, and this Actor's per-dataset license (Creative Commons
Attribution, see below) is TSE's own explicit grant to reuse it.

**Legitimate uses**: PEP screening and AML/compliance checks, journalism
and academic research on candidates' wealth and campaign outcomes, civic
transparency and election-monitoring tools, due diligence before entering
a business relationship with a current or former public official.

**Not an intended use, and this Actor should not be used for**: harassment
or doxxing of candidates or their families, building profiles to target
individuals outside a transparency/compliance/journalism purpose, or using
the demographic fields present in the source data (gender, race/color,
marital status, education level - `raca_cor`, `genero`, `estado_civil`,
`grau_instrucao`) for discriminatory screening of any kind. These fields
are included because TSE publishes them as part of the official candidate
record (Brazil tracks candidate demographics for representation-monitoring
purposes), not as an invitation to filter or discriminate on them - don't.

**CPF is never returned, for every candidate, always** - not a partial
mask like `cnpj-lookup`'s partner CPFs, a hard `null` with an explanatory
`cpf_note`. TSE itself stopped disclosing `NR_CPF_CANDIDATO` in this
dataset (verified directly in the bundled `leiame.pdf` data dictionary,
which quotes Resolução TSE nº 23.609/2019 art. 33 §2º as amended by
Resolução nº 23.729/2024: candidates' CPF, personal address, personal
phone/email, and ID document are withheld from public disclosure and filed
as a sealed document in the candidacy registration process instead). This
is a real, current TSE policy, not a design choice made by this Actor -
confirmed empirically too: every row in the downloaded 2024 file has
`NR_CPF_CANDIDATO = "-4"` (TSE's own sentinel for "not disclosed").
Interestingly, the **in-progress 2026 dataset does still show real CPF
digits** as of this build (2026-08-17) - one more reason "most recent
complete cycle" (2024) and "most recent cycle" (2026) are genuinely
different datasets with different disclosure properties, not just
different years of the same thing.

### Why the 2024 cycle, not 2026

As of this build (2026-08-17), TSE's portal already has a `candidatos-2026`
dataset (Brazil's next general election is October 2026, and the candidacy
registration deadline already passed). It was deliberately **not** used:
2026's data is provisional - candidacies can still be legally challenged
(impugnação) up to and after election day, and there are no final "elected/
not elected" results yet. **2024** (the last municipal elections) is the
most recent dataset where every candidacy has gone through final judicial
review and every race has a final, adjudicated result - a meaningfully
different reliability guarantee, not just an older number. This also means
every 2024 record's `situacao_candidatura` (`DEFERIDO`/`INDEFERIDO`/etc.)
and `situacao_final` (`ELEITO`/`NÃO ELEITO`/etc.) reflect a settled outcome.

### Scope: candidates + assets, not campaign donations (for now)

TSE also publishes campaign-finance data ("Prestação de Contas Eleitorais")

- itemized donations and expenses per candidate. It was evaluated and
  **deliberately excluded from this V1**: the 2024 candidate-finance file
  alone (`prestacao_de_contas_eleitorais_candidatos_2024.zip`) is **1.35GB**
  compressed - roughly 20x the combined size of the candidate-profile (63MB)
  and declared-assets (44MB) files this Actor actually uses - and splits
  across separate revenue/expense/donor sub-files with their own distinct
  schemas. That's a materially different, much larger engineering effort
  (most plausibly a self-hosted/pre-indexed dataset rather than a per-run
  bulk download, the same option-(a)-vs-(b) trade-off `cnpj-lookup` made
  explicit for the Receita Federal CNPJ dump) than a clean V1 batch-lookup
  product justifies before this Actor has any real, validated demand. If
  this Actor gets real paid usage, campaign-finance/donation search is the
  natural next product to evaluate - not built here.

### Pricing

Pay-per-event: **you are charged once per unique candidate matched and
returned** (event `candidate-record`), deduped across election rounds (a
candidate who appears in both the first and second round of a mayoral race
is one charged record, with both rounds' results in `rounds`). A name
query that matches zero candidates is not charged. See the Actor's Store
page for the current per-event price.

**Pricing rationale**: set at the same tier as
[`pncp-lookup`](https://apify.com/jgoia/pncp-lookup) ($0.02/record, 2x
`cnpj-lookup`'s $0.01), for a different reason than PNCP's own (PNCP is
priced up for live-API rate-limiting/latency; this Actor's underlying
source has no rate limit at all - it's static bulk files). Here the cost
driver is data volume and join complexity: every search downloads and
scans TSE's bulk candidate CSV (single-state or, for a nationwide search,
all 26 states' files, ~240MB uncompressed total), then does a second
targeted pass to join party/coligation/status detail and declared-assets
data - a richer, multi-source-joined record than `cnpj-lookup`'s single-API
lookup, even though (unlike PNCP) there's no per-request network
round-trip cost or rate limit driving it.

### Data source, access method & terms of use

**Source**: [Portal de Dados Abertos do TSE](https://dadosabertos.tse.jus.br/)
(Tribunal Superior Eleitoral), Brazil's electoral court's official open-data
portal. It runs CKAN (confirmed via the portal's own `generator` meta tag
and its live REST API, `/api/3/action/package_show`, fetched 2026-08-17).

**Access method - bulk file downloads, not a per-record API**: unlike this
developer's other Aurora Actors, CKAN's REST API here only returns
*dataset metadata* (title, resource list, license, update frequency) -
there is no query/search endpoint for individual candidate records. The
actual data is published exclusively as ZIP-of-CSV bulk downloads on
`cdn.tse.jus.br`, refreshed on TSE's own schedule ("Frequência de
atualização: Diária" per the dataset's own CKAN metadata). This Actor
downloads the relevant ZIP(s) directly from `cdn.tse.jus.br` on each run
and searches them in-process - see "For the Aurora project" below for the
full design rationale.

**License - explicit and per-dataset, verified directly, not inferred**:
every dataset returned by the CKAN API (including `candidatos-2024`, the
one this Actor uses) carries `"license_id": "cc-by"`,
`"license_title": "Creative Commons Attribution"` as structured metadata,
confirmed live via `package_show?id=candidatos-2024` (2026-08-17). CC-BY is
a standard, unambiguous license that explicitly permits commercial reuse,
requiring only attribution - the strongest, most explicit legal basis of
any Aurora Actor's data source so far (stronger than an inferred statutory
argument, and unlike a source's terms simply not prohibiting resale).

This is independently corroborated by the portal's own public FAQ
(`dadosabertos.tse.jus.br/pages/perguntasfrequentes`, fetched 2026-08-17),
which defines "Dados Abertos" using Brazil's statutory open-data definition
(the same one underpinning `pncp-lookup`'s legal basis, Decreto 8.777/2016):
data "disponibilizados sob licença aberta que permita sua livre utilização,
consumo ou cruzamento, limitando-se a creditar a autoria ou a fonte" (made
available under an open license permitting free use, consumption, or
cross-referencing, limited only to crediting authorship/source).

**One access gap, disclosed rather than glossed over**: TSE's *general*
privacy-policy/terms-of-use page
(`tse.jus.br/transparencia/politica-de-privacidade-e-termos-de-uso`,
linked from the open-data portal's footer) could not be fetched directly
from this environment - it returned HTTP 403 "Access Denied" from an
Akamai edge WAF, reproduced identically via a plain `curl`, a browser-
User-Agent `curl`, and the fetch tool (2026-08-17); a wayback-machine
fallback was also attempted and hit an unrelated rate limit at the same
time. This was **not** treated as a blocker the way DataJud's or
ReceitaWS's explicit prohibitions were (see `DECISIONS.md` ADR-005/009):
those were real prohibition clauses actually read in full; this is an
inability to reach one *general* page, while the *dataset-specific*,
machine-readable license (CC-BY, above) and the portal's own FAQ - both
successfully read in full - independently agree on unrestricted, credited
reuse. If the general terms page turns out to narrow that when it becomes
reachable, that would need to be revisited before this Actor's pricing is
treated as settled.

### Rate limits & fair use

`cdn.tse.jus.br` publishes no rate limit and, being static file hosting
(not a live query API), has no per-record processing cost to protect -
this Actor's own real-world runs (see "What was actually tested vs. not")
took 8-13 seconds end to end, including the download. There is nothing to
tune here comparable to `maxConcurrency` on the other Aurora Actors: this
product's cost driver is file size/scan scope (see `uf`/`cargo` filters
above), not request concurrency, since a search is one download-and-scan
pass, not many independent network calls.

***

### For the Aurora project (internal)

Fourth product, built same-day as \[`bcb-institutions-lookup`],
\[`ceis-lookup`], and \[`anvisa-products-lookup`] per `DECISIONS.md`
ADR-008's owner-directed expansion (see `OPPORTUNITIES.md` and ADR-004/005/
009/010/011 for the pattern this follows and its precedents).

#### Design decision: bulk-download-and-scan, not a live per-record API

Every other Aurora Actor so far calls a live API per input record. TSE's
open-data portal doesn't offer one for candidate data (see "Access method"
above) - only bulk ZIP-of-CSV downloads. Two designs were considered:

1. **(Chosen) Download-and-scan per run**: each Actor run downloads the
   needed ZIP(s) from `cdn.tse.jus.br` (63MB candidate + 30MB complementar
   - 44MB assets, only downloaded if `includeAssets` is set), then searches
     them in-process. No VPS-uptime dependency (runs entirely on Apify's
     infrastructure, same principle as `cnpj-lookup`'s option-(a) choice),
     no infrastructure to maintain, ships immediately. Real downside,
     accepted deliberately: every run re-downloads ~100-140MB even though
     TSE only refreshes daily - there's no cross-run cache (Apify's default
     KV store could hold one, keyed by a conditional `ETag` check, but that
     was left for a later iteration rather than adding complexity before
     this product has any validated demand - see "Not tested" below).
2. **(Not chosen) Self-hosted pre-built index**: download the ZIPs once,
   build a real index (SQLite/similar) on a persistent volume, serve
   queries against that instead of re-scanning CSVs per run. Faster and
   avoids repeat downloads, but needs either VPS-hosted infrastructure
   (this Aurora VPS's uptime becomes a dependency the Actor doesn't have
   today) or Apify's paid persistent-storage tiers - the same class of
   trade-off `cnpj-lookup`'s README already reasoned through for RFB's
   full CNPJ dump, and the same conclusion applies: not justified before
   V1 demand is validated.

Performance turned out much better than the file sizes suggested it might

- see the real timings below.

#### Source research (verified 2026-08-17, not assumed)

- Confirmed CKAN via the portal's live `generator` meta tag and its REST
  API (`/api/3/action/package_list` → 172 datasets; `package_show?id=
  candidatos-2024` → full resource list with direct `cdn.tse.jus.br` URLs).
- Fetched real file sizes via `HEAD` requests before committing to this
  design, not assumed: `consulta_cand_2024.zip` 63.7MB, `consulta_cand_
  complementar_2024.zip` 30.9MB, `bem_candidato_2024.zip` 44.3MB,
  `prestacao_de_contas_eleitorais_candidatos_2024.zip` **1.35GB** (the
  file that drove the campaign-finance exclusion above).
- Downloaded and inspected the real ZIP contents directly: each bundles
  one CSV per state (26 - confirmed Distrito Federal has no municipal
  elections, so is legitimately absent, not a data gap) plus a `_BRASIL`
  duplicate-union file this Actor deliberately never reads (see
  `tse_data.py` module docstring).
- Read the bundled `leiame.pdf` data dictionary in full (via `pdfminer`) -
  the authoritative, dataset-specific source for encoding (Latin-1),
  delimiter (`;`), sentinel values (`#NULO`/`#NE`/`-1`/`-3`/`-4`), and the
  CPF non-disclosure policy quoted verbatim in this README. It contains no
  licensing/terms clauses of its own (checked directly, not assumed) - it's
  purely a technical layout reference.
- Confirmed the CPF-masking finding empirically, not just from the PDF:
  every row of the real downloaded 2024 file has `NR_CPF_CANDIDATO = "-4"`;
  by contrast, the same field in the real downloaded (in-progress)
  `consulta_cand_2026_AP.csv` contains real 11-digit CPF numbers - a
  concrete, verified difference between the two datasets, not a guess.
- Picked São Paulo's mayor (Ricardo Nunes, re-elected 2024,
  `SQ_CANDIDATO 250002098117`) as the real-public-figure fixture per this
  task's own instruction, since he's an unambiguous, verifiable public
  official with a large, real declared-assets list (32 items, ~R$4.8M) -
  good coverage for both the "profile" and "assets" join paths.

#### What was actually tested vs. not

**Tested and passing**: 47/47 tests (`pytest`, Python 3.12 venv - same
reasoning as `cnpj-lookup` for using 3.12 over the VPS's default 3.10, see
that README), covering: accent/case-insensitive name normalization and
substring matching (`name_match.py`); joining multi-round candidate rows,
complementar status rows, and asset rows into one output record, including
the CPF-always-null guarantee, BRL parsing for both of TSE's two decimal
notations, and the "no complementar row found" edge case
(`normalize.py`); ZIP download/caching/streaming-read behavior including a
missing-member (no data for that UF) case and download-failure handling,
via `httpx.MockTransport` - no real network calls in the unit test suite
(`tse_data.py`); and full search orchestration - single-UF and nationwide
scans, cargo filtering, the assets-join toggle, multi-query runs, and
"zero matches" handling (`search.py`). `ruff` clean, zero warnings.
`apify-cli validate-schema` passes for both `input_schema.json` and
`dataset_schema.json`.

All fixtures are **real TSE data** captured 2026-08-17 (trimmed to a
handful of real rows, not synthesized), per this task's instruction to use
a real public figure's public candidacy record - not hand-written mocks
pretending to be TSE's schema.

**Full end-to-end runs against the live internet** (`apify-cli run`, which
reads `.actor/actor.json` exactly as the real platform would) - genuinely
completed, not just attempted:

- Single-state search (`uf: "SP"`, `candidateNames: ["RICARDO NUNES",
  "NOME QUE NAO EXISTE XYZ"]`): **8.5s real time**. Correctly returned 3
  real matches (São Paulo's mayor, `ELEITO`, 32 real assets; two other real
  SP candidates whose full/ballot names contain "RICARDO NUNES") and one
  correct `no_match` record for the nonexistent name.
- Nationwide search (no `uf`, `candidateNames: ["RICARDO NUNES"]`,
  `maxResultsPerName: 5`): **13.1s real time** scanning all 26 states'
  files (~240MB). Correctly returned 5 real distinct candidates from 5
  different states (MA, MG, PR×2, RS) whose names contain "Ricardo Nunes",
  respecting the cap.

Both runs are real production evidence this Actor works end to end against
the live source, not a claim inferred from unit tests alone - a stronger
starting position than `pncp-lookup`'s disclosed pre-deployment gap
(ADR-010/011) or `ceis-lookup`'s (no test API key available locally).

**Not tested / could not verify locally**:

- Real pay-per-event **charging** behavior: same as every other Aurora
  Actor, the SDK correctly no-ops charging outside a real platform run
  (`"Ignored attempt to charge for an event..."` in the local run logs
  above) - the charging code path is exercised on every match, but actual
  billing can only be confirmed after deploying and monetizing.
- **Docker build**: no Docker on this VPS (same constraint as every prior
  Aurora Actor - no root/sudo to install it). The Dockerfile matches the
  other three products' (and Apify's official template) line-for-line
  except the package name.
- **Cross-run caching**: not implemented (see "Design decision" above) -
  every run re-downloads the ZIPs fresh; not yet validated whether real
  usage patterns would make a KV-store cache worth the added complexity.
- The general TSE terms-of-use page (see "Data source... one access gap,
  disclosed rather than glossed over").

#### Deployment (status: built, not yet deployed - no owner-only blocker)

Unlike `ceis-lookup` (blocked on a Gov.br API key only a human can obtain),
this product needs **no owner action before deployment** - same as
`cnpj-lookup`/`pncp-lookup`, since `cdn.tse.jus.br` needs no API key,
account, or credential of any kind.

1. `npx apify-cli push` from this directory.
2. Real smoke test on Apify's own infrastructure (`apify-cli call`), the
   same way ADR-011 re-verified `pncp-lookup` after this VPS's own
   downloads: e.g. `-i '{"candidateNames": ["RICARDO NUNES"], "uf": "SP"}'`
   and confirm the mayor's real record comes back with 32 assets.
3. Set pay-per-event pricing and publish via the Apify REST API, the same
   calls already proven working three times (`cnpj-lookup` ADR-006/007,
   `pncp-lookup` ADR-011) - should need **no owner action** for the
   publish step itself, since payout billing info, public profile, and
   Store Terms acceptance are account-level settings that already carried
   over from `cnpj-lookup`'s first deployment.
4. Report real usage/revenue into `BUSINESS.md` once it exists - do not
   fabricate numbers before they exist.

# Actor input Schema

## `candidateNames` (type: `array`):

List of candidate names (full legal name or ballot/urna name) to search for, one per line/item. Matching is case-insensitive and accent-insensitive substring matching against both the legal name and the ballot name.

## `uf` (type: `string`):

Optional 2-letter Brazilian state code (e.g. SP, RJ, MG) to restrict every search in this run to one state. Greatly speeds up the search - omit to search all 26 states (Distrito Federal has no municipal election and is not in this dataset), which is slower since it scans every state's file.

## `cargo` (type: `string`):

Optional office filter for the 2024 municipal elections.

## `includeAssets` (type: `boolean`):

Whether to join each matched candidate's declared-assets records (bens declarados) into the output. Adds a second, targeted read (scoped only to the states of the matched candidates, not a full nationwide scan) - does not change what is charged.

## `maxResultsPerName` (type: `integer`):

Cap on how many matching candidates are returned for each name query, to bound output for very common names. Max 50.

## Actor input object example

```json
{
  "candidateNames": [
    "RICARDO NUNES"
  ],
  "includeAssets": true,
  "maxResultsPerName": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "candidateNames": [
        "RICARDO NUNES"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jgoia/tse-electoral-lookup").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "candidateNames": ["RICARDO NUNES"] }

# Run the Actor and wait for it to finish
run = client.actor("jgoia/tse-electoral-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "candidateNames": [
    "RICARDO NUNES"
  ]
}' |
apify call jgoia/tse-electoral-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jgoia/tse-electoral-lookup"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/o7d1koDaZT0yx6P2q/builds/PfphhkfxII7zdG2zh/openapi.json
