Skip to contents

Overview

The ANS (Agencia Nacional de Saude Suplementar) is Brazil’s regulatory agency for private/supplementary health insurance (planos de saude). Its open data portal provides data on beneficiaries, consumer complaints, and operator financial statements.

Feature Details
Source HTTP CSV/ZIP (dadosabertos.ans.gov.br)
Data types 3 (beneficiaries, complaints, financial)
Beneficiaries Monthly, per-UF (Apr 2019–present)
Complaints Annual, national (2011–present)
Financial Quarterly (2007–present)
Operators Snapshot registry (separate function)

Data types

Code Name Granularity Availability
beneficiaries Beneficiarios Monthly, per-UF Apr 2019–2025
complaints Demandas NIP Annual, national 2011–2026
financial Demonstracoes contabeis Quarterly 2007–2025

Getting started

Check available years

# beneficiaries (default)
ans_years()

# complaints
ans_years(type = "complaints")

# financial statements
ans_years(type = "financial")

Module information

Beneficiaries

Beneficiary data provides consolidated counts of health plan enrollees broken down by operator, municipality, sex, age group, plan type, and more. Each file covers one state (UF) and one month.

Basic download

# Acre, December 2023
ac <- ans_data(year = 2023, month = 12, uf = "AC")
ac

Multiple months and states

# first quarter 2024, two states
ne <- ans_data(year = 2024, month = 1:3, uf = c("CE", "PE"))

# full year (month = NULL downloads all 12 months)
ac_2023 <- ans_data(year = 2023, uf = "AC")

Selecting variables

ans_data(
  year = 2023, month = 12, uf = "AC",
  vars = c("CD_OPERADORA", "SG_UF", "TP_SEXO",
           "DE_FAIXA_ETARIA", "QT_BENEFICIARIO_ATIVO")
)

Key variables

Variable Description
ID_CMPT_MOVEL Reference period (YYYY-MM)
CD_OPERADORA Operator code at ANS
NM_RAZAO_SOCIAL Operator name
SG_UF State abbreviation
CD_MUNICIPIO Municipality (IBGE code)
TP_SEXO Sex (M/F)
DE_FAIXA_ETARIA Age group
DE_CONTRATACAO_PLANO Contract type (Individual, Coletivo Empresarial, etc.)
DE_SEGMENTACAO_PLANO Plan segment (Ambulatorial, Hospitalar, etc.)
COBERTURA_ASSIST_PLAN Coverage type (Medico-hospitalar, Odontologica)
TIPO_VINCULO Beneficiary link (Titular, Dependente)
QT_BENEFICIARIO_ATIVO Active beneficiary count

Consumer complaints (NIP)

Consumer complaints data covers demands filed through ANS’s NIP (Notificacao de Intermediacao Preliminar) system. Files are national (not per-UF) and annual.

# complaints filed in 2022
nip <- ans_data(year = 2022, type = "complaints")
nip

# multiple years
nip_multi <- ans_data(year = 2020:2023, type = "complaints")

Key variables

Variable Description
NUMERO_DA_DEMANDA Complaint number
ABERTURA_DA_DEMANDA Filing date
ASSUNTO Subject
REGISTRO_OPERADORA Operator registration
NOME_OPERADORA Operator name
TIPO_DE_PLANO_CONTRATADO Contract type
SEXO Sex (M/F)
ESTADO_DO_BENEFICIARIO Beneficiary state
CLASSIFICACAO_DA_NIP NIP classification
NATUREZA_DA_NIP NIP nature
SITUACAO_DA_NIP NIP status

Financial statements

Quarterly financial statements (demonstracoes contabeis) for all health plan operators.

# Q1 2023
fin_q1 <- ans_data(year = 2023, type = "financial", quarter = 1)

# all 4 quarters of 2023
fin_2023 <- ans_data(year = 2023, type = "financial")

# specific quarters
fin_q12 <- ans_data(year = 2023, type = "financial", quarter = 1:2)

Key variables

Variable Description
DATA Reference date
REG_ANS Operator registration
CD_CONTA_CONTABIL Accounting code
DESCRICAO Account description
VL_SALDO_INICIAL Opening balance (R)||VLSALDOFINAL|Closingbalance(R) | | VL_SALDO_FINAL | Closing balance (R)

Operator registry

The operator registry is a separate snapshot (not time-series), so it uses its own function:

# active operators
active <- ans_operators()

# cancelled operators
cancelled <- ans_operators(status = "cancelled")

# both combined
all_ops <- ans_operators(status = "all")

Key variables

Variable Description
REGISTRO_OPERADORA ANS registration number
CNPJ Tax ID
Razao_Social Legal name
Nome_Fantasia Trade name
Modalidade Modality (Medicina de Grupo, Cooperativa, etc.)
UF State
Data_Registro_ANS ANS registration date

Exploring variables

# beneficiaries variables (default)
ans_variables()

# complaints variables
ans_variables(type = "complaints")

# financial variables
ans_variables(type = "financial")

# search across variables
ans_variables(search = "operadora")
ans_variables(search = "beneficiario")

Example: beneficiaries by state and plan type

# December 2023, all states
ben <- ans_data(year = 2023, month = 12)

# active beneficiaries by state and coverage type
ben |>
  group_by(SG_UF, COBERTURA_ASSIST_PLAN) |>
  summarize(
    total = sum(as.integer(QT_BENEFICIARIO_ATIVO), na.rm = TRUE),
    .groups = "drop"
  ) |>
  arrange(desc(total))

Example: complaints by subject and operator

nip <- ans_data(year = 2023, type = "complaints")

# top complaint subjects
nip |>
  count(ASSUNTO, sort = TRUE) |>
  head(10)

# operators with most complaints
nip |>
  count(NOME_OPERADORA, sort = TRUE) |>
  head(10)

Example: operator financial health

# Q4 2023 financial data
fin <- ans_data(year = 2023, type = "financial", quarter = 4)

# join with operator registry for names
ops <- ans_operators()

fin |>
  filter(grepl("^41", CD_CONTA_CONTABIL)) |>  # revenue accounts
  group_by(REG_ANS) |>
  summarize(
    revenue = sum(as.numeric(VL_SALDO_FINAL), na.rm = TRUE),
    .groups = "drop"
  ) |>
  left_join(
    ops |> select(REGISTRO_OPERADORA, Razao_Social),
    by = c("REG_ANS" = "REGISTRO_OPERADORA")
  ) |>
  arrange(desc(revenue)) |>
  head(10)

Example: combining ANS with SUS data

ANS beneficiary counts complement SUS data by showing private coverage:

# private coverage (ANS)
ben <- ans_data(year = 2023, month = 12,
                vars = c("SG_UF", "QT_BENEFICIARIO_ATIVO"))

private_by_uf <- ben |>
  group_by(SG_UF) |>
  summarize(
    private_beneficiaries = sum(as.integer(QT_BENEFICIARIO_ATIVO), na.rm = TRUE),
    .groups = "drop"
  )

# total population (Census 2022)
pop <- censo_populacao(year = 2022, territorial_level = "state")

# private coverage rate
# private_by_uf |>
#   left_join(pop, by = ...) |>
#   mutate(coverage_pct = (private_beneficiaries / population) * 100) |>
#   arrange(desc(coverage_pct))

Parameter routing

ans_data() routes parameters based on the type:

Parameter beneficiaries complaints financial
year required required required
month optional (1–12) ignored ignored
uf optional (27 UFs + XX) ignored ignored
quarter ignored ignored optional (1–4)
vars optional optional optional

Unused parameters emit a warning but do not cause errors.

Lazy evaluation

With the arrow package installed, data is cached in Parquet format and can be queried lazily:

# lazy query (requires arrow)
lazy_ben <- ans_data(year = 2023, uf = "AC", lazy = TRUE)
lazy_ben |>
  filter(month == 12L, TP_SEXO == "F") |>
  select(CD_OPERADORA, DE_FAIXA_ETARIA, QT_BENEFICIARIO_ATIVO) |>
  collect()

Cache management

Downloaded data is cached locally for faster future access:

# check cache status
ans_cache_status()

# clear cache if needed
ans_clear_cache()

Differences from DATASUS modules

Feature ANS DATASUS modules
Data source HTTP CSV/ZIP FTP .dbc/.DBF files
Column names MixedCase (from CSV) UPPERCASE
parse parameter Not available Available
dictionary() Not available Available
quarter parameter Financial data Not used
Operator registry ans_operators() Not applicable

Additional resources

  • ANS open data portal (dadosabertos.ans.gov.br)
  • ANS official website (www.gov.br/ans/pt-br)
  • ANS Tabnet (www.ans.gov.br/anstabnet)
  • Census vignette for population denominators