Ir para o conteúdo

API IBGE

O módulo IBGE fornece acesso aos dados do Sistema IBGE de Recuperação Automática (SIDRA). A malha municipal e as áreas urbanizadas vêm do WFS dos geoserviços do IBGE (malha_municipal e areas_urbanizadas).

As consultas SIDRA usam HTTP assíncrono direto, com timeout total de 120 segundos por tentativa, cancelamento e retry exponencial de falhas transitórias. Não há uma thread de transporte pendente após timeout. A montagem da consulta segue os parâmetros oficiais do SIDRA.

Na API 2.0, os filtros territoriais e as flags são passados por nome. PAM, LSPA, PPM, silvicultura e extração vegetal aceitam apenas produto/espécie e ano por posição; abate aceita espécie e trimestre; censos aceitam apenas tema. No PIB, apenas setor é posicional: use ibge.pib_agro(trimestre="202401"). Leite aceita apenas trimestre por posição.

Domínios fechados normalizam caixa e acentos; parâmetros inválidos levantam InvalidParameterError antes da consulta. variaveis=[], variáveis desconhecidas e listas de anos vazias são recusadas. Silvicultura e extração vegetal validam o ano entre 1974 e o ano corrente. O censo histórico aceita ano inteiro ou lista não vazia de inteiros publicados para o tema.

Cada consulta SIDRA vazia emite um aviso e registra o mesmo texto em MetaInfo.validation_warnings, inclusive quando outra consulta da mesma tabela e período já veio vazia. Colunas e dtypes são preservados no vazio: anos/códigos em Int64, medidas em float64, rótulos de trimestre em texto e texto no padrão do pandas instalado. animais_abatidos usa Int64 (contrato 2.0); quantidade fracionária gera ParseError. A PAM preserva suas 14 colunas de saída, com medidas não solicitadas nulas.

Funções

pam

Obtém dados da Produção Agrícola Municipal.

async def pam(
    produto: str,
    ano: int | float | str | Sequence[int | float | str] | None = None,
    *,
    uf: str | None = None,
    nivel: Literal["brasil", "uf", "municipio"] = "uf",
    variaveis: list[str] | None = None,
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame  # (df, MetaInfo) se return_meta=True

Parâmetros:

Parâmetro Tipo Descrição
produto str Código do produto (ex: 'soja', 'milho')
ano int \| str \| list[int] \| None Ano(s). Default: último disponível
uf str \| None Filtrar por UF (ex: 'MT')
nivel Literal['brasil', 'uf', 'municipio'] Nível: 'brasil', 'uf', 'municipio'
variaveis list[str] \| None Variáveis pedidas. Padrão: area_plantada, area_colhida, producao e rendimento; valor_producao só vem quando pedido (variaveis=[..., 'valor_producao']), e sem ele a coluna sai nula
as_polars bool Retornar como polars.DataFrame
return_meta bool Retorna (df, MetaInfo) com proveniência

Variáveis disponíveis:

Código Variável
area_plantada Área plantada (hectares)
area_colhida Área colhida (hectares)
producao Quantidade produzida (ver unidade_producao)
rendimento Rendimento médio (ver unidade_rendimento)
valor_producao Valor da produção (ver unidade_valor_producao)

Exemplo:

from agrobr import ibge

# PAM por UF
df = await ibge.pam('soja', ano=2023, nivel='uf')

# Múltiplos anos
df = await ibge.pam('soja', ano=[2020, 2021, 2022, 2023])

# Por município (filtrar UF para reduzir volume)
df = await ibge.pam('soja', ano=2023, nivel='municipio', uf='MT')

# Variáveis específicas
df = await ibge.pam('soja', ano=2023, variaveis=['producao', 'area_plantada'])

lspa

Obtém dados do Levantamento Sistemático da Produção Agrícola.

async def lspa(
    produto: str,
    ano: int | str | None = None,
    *,
    mes: int | str | None = None,
    uf: str | None = None,
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame  # (df, MetaInfo) se return_meta=True

Parâmetros:

Parâmetro Tipo Descrição
produto str Código do produto
ano int \| str \| None Ano. Default: atual
mes int \| str \| None Mês (1-12). Sem filtro: meses disponíveis do ano solicitado
uf str \| None UF da consulta. Sem uf, a saída é só o total Brasil; para várias UFs, faça uma chamada por UF
as_polars bool Retornar como polars.DataFrame
return_meta bool Retorna (df, MetaInfo) com proveniência

O contrato LSPA 2.0 retorna uma linha por ano, mês, localidade, produto e variável. mes sempre está presente; variavel, variavel_cod e unidade identificam a medida. datasets.estimativa_safra continua consolidando o mês mais recente e convertendo às unidades do próprio contrato.

Produtos LSPA (21 códigos, além dos aliases):

Código Produto
soja Soja
milho_1 Milho 1ª safra
milho_2 Milho 2ª safra
arroz Arroz
feijao_1 Feijão 1ª safra
feijao_2 Feijão 2ª safra
feijao_3 Feijão 3ª safra
trigo Trigo
algodao Algodão herbáceo em caroço
cafe_arabica Café arábica (desde 2012)
cafe_canephora Café canephora (desde 2012)
amendoim_1 Amendoim 1ª safra
amendoim_2 Amendoim 2ª safra
aveia Aveia
batata_1 Batata-inglesa 1ª safra
batata_2 Batata-inglesa 2ª safra
batata_3 Batata-inglesa 3ª safra
cevada Cevada
mamona Mamona
sorgo Sorgo
triticale Triticale

Aliases genéricos:

Nomes genéricos expandem automaticamente para sub-safras e retornam um DataFrame concatenado:

Alias Expande para
milho milho_1 + milho_2
feijao feijao_1 + feijao_2 + feijao_3
amendoim amendoim_1 + amendoim_2
batata batata_1 + batata_2 + batata_3
cafe Total oficial até 2011; cafe_arabica + cafe_canephora desde 2012

As espécies e safras permanecem separadas em produto. O total histórico de café usa produto="cafe". Rendimentos não são aditivos; para um agregado, calcule produção × 1.000 / área colhida. produtos_lspa() inclui códigos e aliases.

Exemplo:

from agrobr import ibge

# LSPA mensal
df = await ibge.lspa('soja', ano=2024, mes=6)

# Milho 2ª safra
df = await ibge.lspa('milho_2', ano=2024)

# Alias genérico — retorna milho_1 + milho_2 concatenados
df = await ibge.lspa('milho', ano=2024)

# Por UF
df = await ibge.lspa('soja', ano=2024, uf='MT')

produtos_pam

Lista produtos disponíveis na PAM.

async def produtos_pam() -> list[str]

produtos_lspa

Lista produtos disponíveis no LSPA.

async def produtos_lspa() -> list[str]

ppm

Obtém dados da Pesquisa da Pecuária Municipal.

async def ppm(
    especie: str,
    ano: int | str | list[int] | None = None,
    *,
    uf: str | None = None,
    nivel: Literal["brasil", "uf", "municipio"] = "uf",
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame  # (df, MetaInfo) se return_meta=True

Parâmetros:

Parâmetro Tipo Descrição
especie str Espécie ou produto (ex: 'bovino', 'leite')
ano int \| str \| list[int] \| None Ano(s). Default: último disponível
uf str \| None Filtrar por UF (ex: 'MT')
nivel Literal['brasil', 'uf', 'municipio'] Nível: 'brasil', 'uf', 'municipio'
as_polars bool Retornar como polars.DataFrame
return_meta bool Retorna (df, MetaInfo) com proveniência

Espécies disponíveis (rebanhos):

Código Espécie
bovino Bovino
bubalino Bubalino
equino Equino
suino_total Suíno (total)
suino_matrizes Suíno matrizes
caprino Caprino
ovino Ovino
galinaceos_total Galináceos (total)
galinhas Galinhas (categoria IBGE "Galináceos - galinhas": inclui poedeiras e matrizeiras)
codornas Codornas

galinhas_poedeiras segue aceito como alias depreciado de galinhas, com FutureWarning; a saída vem com especie="galinhas".

Produtos de origem animal:

Código Produto Unidade
leite Leite mil litros
ovos_galinha Ovos de galinha mil dúzias
ovos_codorna Ovos de codorna mil dúzias
mel Mel de abelha kg
casulos Casulos bicho-da-seda kg
la Lã kg

Exemplo:

from agrobr import ibge

# Rebanho bovino por UF
df = await ibge.ppm('bovino', ano=2023, nivel='uf')

# Produção de leite por município em MG
df = await ibge.ppm('leite', ano=2023, nivel='municipio', uf='MG')

# Série histórica
df = await ibge.ppm('bovino', ano=[2019, 2020, 2021, 2022, 2023])

# Com metadados
df, meta = await ibge.ppm('bovino', ano=2023, return_meta=True)

especies_ppm

Lista espécies e produtos disponíveis na PPM.

async def especies_ppm() -> list[str]

abate

Obtém dados da Pesquisa Trimestral do Abate de Animais.

async def abate(
    especie: str,
    trimestre: str | list[str] | None = None,
    *,
    uf: str | None = None,
    categoria: str = "total",
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame  # (df, MetaInfo) se return_meta=True

Parâmetros:

Parâmetro Tipo Descrição
especie str Espécie: 'bovino', 'suino', 'frango'
trimestre str \| list[str] \| None Trimestre YYYYQQ (ex: '202303'). Default: último disponível
uf str \| None Filtrar por UF (ex: 'PR')
categoria str Tipo de rebanho, só no bovino (classificação 18 da tabela 1092): 'total' (padrão), 'bois', 'vacas', 'novilhos', 'novilhas', 'vitelos' ou 'todas' (o total e as 5 categorias). No suíno e no frango, só 'total'; outro valor levanta InvalidParameterError antes da rede
as_polars bool Retornar como polars.DataFrame
return_meta bool Retorna (df, MetaInfo) com proveniência

Espécies disponíveis:

Código Espécie Tabela SIDRA
bovino Bovino 1092
suino Suíno 1093
frango Frango 1094

Variáveis retornadas:

Variável Descrição Unidade
animais_abatidos Quantidade de animais abatidos cabeças
peso_carcacas Peso total das carcaças kg

A coluna categoria diz o tipo de rebanho da linha (total no suíno e no frango). Com categoria='todas', cada UF e trimestre sai em 6 linhas. No 3º trimestre de 2023, bois, vacas, novilhos e novilhas somam o total em 21 das 27 UFs; nas outras 6, o IBGE omite alguma categoria por sigilo (célula X, nula na saída). vitelos saiu sem dado (..., nulo) em todas as UFs.

Exemplo:

from agrobr import ibge

# Abate bovino por UF
df = await ibge.abate('bovino', trimestre='202303')

# Participação de fêmeas (vacas + novilhas) no abate bovino, por UF
df = await ibge.abate('bovino', trimestre='202303', categoria='todas')
cabecas = df.pivot(index='localidade', columns='categoria', values='animais_abatidos')
femeas = (cabecas['vacas'] + cabecas['novilhas']) / cabecas['total']
# Mato Grosso: (365.311 + 306.266) / 1.602.321 = 0,419

# Abate de frango no Paraná
df = await ibge.abate('frango', trimestre='202303', uf='PR')

# Abate de suínos — todas as UFs
df = await ibge.abate('suino', trimestre='202304')

# Com metadados
df, meta = await ibge.abate('bovino', trimestre='202303', return_meta=True)

especies_abate

Lista espécies disponíveis no Abate Trimestral.

async def especies_abate() -> list[str]

censo_agro

Obtém dados do Censo Agropecuário (1995, 2006 e 2017).

async def censo_agro(
    tema: str,
    *,
    ano: int | str | None = None,
    uf: str | None = None,
    nivel: Literal["brasil", "uf", "municipio"] = "uf",
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame  # (df, MetaInfo) se return_meta=True

Parâmetros:

Parâmetro Tipo Descrição
tema str Tema do censo (ver tabela abaixo)
ano int \| str \| None Ano censal (1995, 2006 ou 2017). Default: todos os anos disponíveis
uf str \| None Filtrar por UF (ex: 'MT')
nivel Literal['brasil', 'uf', 'municipio'] Nível: 'brasil', 'uf', 'municipio'
as_polars bool Retornar como polars.DataFrame
return_meta bool Retorna (df, MetaInfo) com proveniência

Temas disponíveis:

Código Tema Tabela 1995 Tabela 2006 Tabela 2017
efetivo_rebanho Efetivo de rebanho 323 — 6907
uso_terra Uso da terra 316/311 — 6881
lavoura_temporaria Lavoura temporária 497/492/503 — 6957
lavoura_permanente Lavoura permanente 509/504/510 — 6956
preparo_solo Preparo do solo — 791 6855
adubacao Adubação — 1249 6848
calagem Calagem — 1245 6849
agrotoxicos Uso de agrotóxicos — 1459 6851
praticas_agricolas Práticas agrícolas — 837 8561
irrigacao Irrigação — 855 6857
despesa_adubos Despesa com adubos e corretivos — — 6899

Variáveis retornadas por tema (temas originais):

Tema Variável Unidade
efetivo_rebanho estabelecimentos unidades
efetivo_rebanho cabecas cabeças
uso_terra estabelecimentos unidades
uso_terra area hectares
lavoura_temporaria estabelecimentos (2017) ou informantes (1995) unidades
lavoura_temporaria producao varia
lavoura_temporaria area_colhida hectares
lavoura_permanente estabelecimentos (2017) ou informantes (1995) unidades
lavoura_permanente producao varia
lavoura_permanente area_colhida hectares

Em 1995, as lavouras publicam informantes: a variável 151 da SIDRA (tabelas 492 e 504), que a SIDRA chama de "Número de informantes". Em 2017, estabelecimentos é o "Número de estabelecimentos agropecuários com lavoura temporária" (10084) e, na permanente, "com 50 pés e mais existentes" (9504).

Categorias dos novos temas (exemplos):

Tema Categorias (exemplos)
preparo_solo Cultivo convencional, Cultivo mínimo, Plantio direto na palha
adubacao Química, Orgânica, Adubação verde
calagem Fez aplicação, Não fez aplicação
agrotoxicos Utilizou, Não utilizou
praticas_agricolas Plantio em nível, Rotação de culturas, Pousio
irrigacao Gotejamento, Pivô central, Inundação, Aspersão
despesa_adubos Estabelecimentos com despesa, valor da despesa

Exemplo:

from agrobr import ibge

# Efetivo de rebanho por UF (1995 e 2017)
df = await ibge.censo_agro('efetivo_rebanho')

# Uso da terra em Mato Grosso
df = await ibge.censo_agro('uso_terra', uf='MT')

# Lavoura temporária por município
df = await ibge.censo_agro('lavoura_temporaria', nivel='municipio', uf='PR')

# Preparo do solo — ambos os anos (2006 + 2017)
df = await ibge.censo_agro('preparo_solo')

# Irrigação apenas 2017
df = await ibge.censo_agro('irrigacao', ano=2017)

# Adubação em 2006, filtrado por UF
df = await ibge.censo_agro('adubacao', ano=2006, uf='SP')

# Com metadados
df, meta = await ibge.censo_agro('efetivo_rebanho', return_meta=True)

temas_censo_agro

Lista temas disponíveis no Censo Agropecuário.

async def temas_censo_agro() -> list[str]

censo_agro_legado

Obtém dados do Censo Agropecuário 1995/96 — seis temas via FTP, em ZIPs com tabelas XLS ou HTML.

O contrato 2.1 distingue Brasil, totais estaduais e municípios pelas tabelas oficiais. nivel='uf' é o padrão e consulta as 27 UFs quando uf não é informado. nivel='brasil' inclui as categorias nacionais de atividade e não aceita filtro uf. A coluna uf identifica o estado de municípios homônimos; códigos municipais ausentes na fonte permanecem nulos. Variáveis e unidades vêm dos cabeçalhos reais. O IBGE não publica a tabela municipal de máquinas do Pará (o Para/Tab_7Mn.zip traz a Tabela 6, de pessoal ocupado): tema='maquinas' sem uf devolve as outras 26 UFs, com o aviso em MetaInfo.validation_warnings e um UserWarning, e uf='PA' levanta SourceUnavailableError.

async def censo_agro_legado(
    tema: str,
    *,
    uf: str | None = None,
    nivel: Literal["brasil", "uf", "municipio"] = "uf",
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame  # (df, MetaInfo) se return_meta=True

Parâmetros:

Parâmetro Tipo Descrição
tema str Tema legado (ver tabela abaixo)
uf str \| None Filtrar por UF (ex: 'SP')
nivel Literal['brasil', 'uf', 'municipio'] Nível: 'brasil', 'uf', 'municipio'
as_polars bool Retornar como polars.DataFrame
return_meta bool Retorna (df, MetaInfo) com proveniência

Temas disponíveis:

Código Tema
tecnologia Tecnologia (assistência técnica, irrigação, adubos, etc.)
pessoal_ocupado Pessoal ocupado (total, familiar, permanentes, temporários)
maquinas Máquinas e equipamentos (tratores por faixa de CV)
producao_animal Produção animal (leite, lã, ovos)
valor_producao Valor da produção (vegetal, animal, subtipos)
financeiro Dados financeiros (investimentos, financiamentos, despesas, receitas)

Exemplo:

from agrobr import ibge

# Tecnologia por UF
df = await ibge.censo_agro_legado('tecnologia')

# Pessoal ocupado em São Paulo
df = await ibge.censo_agro_legado('pessoal_ocupado', uf='SP')

# Máquinas nos municípios de Goiás
df = await ibge.censo_agro_legado('maquinas', uf='GO', nivel='municipio')

# Com metadados
df, meta = await ibge.censo_agro_legado('tecnologia', return_meta=True)

temas_censo_agro_legado

Lista temas disponíveis no Censo Agropecuário Legado (FTP).

async def temas_censo_agro_legado() -> list[str]

censo_agro_historico

Obtém dados da série histórica do Censo Agropecuário (1920-2006, nível UF máximo).

async def censo_agro_historico(
    tema: str,
    *,
    ano: int | list[int] | None = None,
    uf: str | None = None,
    nivel: Literal["brasil", "regiao", "uf"] = "uf",
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame  # (df, MetaInfo) se return_meta=True

Parâmetros:

Parâmetro Tipo Descrição
tema str Tema da série histórica (ver tabela abaixo)
ano int \| list[int] \| None Ano(s) censal(ais). Default: todos os disponíveis
uf str \| None Filtrar por UF (ex: 'SP'). Exige nivel='uf'; com 'brasil' ou 'regiao', levanta InvalidParameterError
nivel Literal['brasil', 'regiao', 'uf'] Nível: 'brasil', 'regiao', 'uf' (municipal NÃO disponível)
as_polars bool Retornar como polars.DataFrame
return_meta bool Retorna (df, MetaInfo) com proveniência

Temas disponíveis:

Código Tema Tabela SIDRA Períodos
estabelecimentos_area Estabelecimentos e área por grupo de área 263 1920-2006 (10 censos)
uso_terra Área por utilização das terras 264 1970-2006 (6 censos)
pessoal_tratores Pessoal ocupado e tratores 265 1970-2006 (6 censos)
condicao_produtor Estabelecimentos por condição do produtor 280 1920-2006 (10 censos)
efetivo_animais Efetivo de animais por espécie 281 1970-2006 (6 censos)
producao_animal Produção animal por tipo 282 1920-2006 (10 censos)
producao_vegetal Produção vegetal e área colhida 283 1920-2006 (10 censos)
lavoura_permanente Quantidade produzida — lavouras permanentes 1730 1940-2006 (9 censos)
lavoura_temporaria Quantidade produzida — lavouras temporárias 1731 1940-2006 (9 censos)

Exemplo:

from agrobr import ibge

# Estabelecimentos e área, Brasil, 1985
df = await ibge.censo_agro_historico('estabelecimentos_area', ano=1985, nivel='brasil')

# Efetivo de animais, todas as UFs, todos os censos
df = await ibge.censo_agro_historico('efetivo_animais')

# Pessoal e tratores em São Paulo, 1980 e 1985
df = await ibge.censo_agro_historico('pessoal_tratores', ano=[1980, 1985], uf='SP')

# Produção vegetal, nível região
df = await ibge.censo_agro_historico('producao_vegetal', nivel='regiao')

# Com metadados
df, meta = await ibge.censo_agro_historico('uso_terra', ano=1985, return_meta=True)

temas_censo_agro_historico

Lista temas disponíveis na série histórica do Censo Agropecuário.

async def temas_censo_agro_historico() -> list[str]

CLI

# Todos os dados de estabelecimentos/área por UF
agrobr ibge censo-historico estabelecimentos_area

# Ano específico, formato CSV
agrobr ibge censo-historico uso_terra --ano 1985 --formato csv

# Múltiplos anos, nível Brasil
agrobr ibge censo-historico efetivo_animais --ano 1970,1985,2006 --nivel brasil

# Filtrar por UF
agrobr ibge censo-historico pessoal_tratores --ano 1985 --uf SP

# Listar temas disponíveis
agrobr ibge temas-historico

censo_agro_municipal_1985

Censo Agropecuário 1985, tabelas municipais 67 a 119 dos 28 volumes estaduais do IBGE (27 UFs; Minas Gerais em 2 volumes). O agrobr extraiu os números dos PDFs do IBGE e os traz num pacote local (agrobr/data/censo_1985/): a consulta não usa a rede.

async def censo_agro_municipal_1985(
    tema: str,
    *,
    uf: str | None = None,
    nivel: str | None = None,
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | tuple[pd.DataFrame, MetaInfo]
  • 1 linha por casa do PDF, com o status de cada uma: a casa do número e também as sem leitura, as sem coluna identificada e as fora da grade.
  • valor só vem na casa confirmada pelas somas impressas (município → microrregião → mesorregião → UF). valor_lido traz a leitura sempre. Filtre por status para escolher o nível de confiança; a precisão medida de cada status está no contrato.
  • tema: um dos 53 temas (temas_censo_agro_municipal_1985()), um por tabela, pelo título impresso.
  • uf: sigla. A UF cujo volume não traz a tabela levanta InvalidParameterError com o motivo (o IBGE omite a tabela que não se aplica ao estado). A tabela que está no volume, mas de que a extração não leu nenhuma casa (AM 80, AP 80, RR 80 e RR 119), levanta ParseError com as páginas e o motivo.
  • nivel: uf, mesorregiao, microrregiao ou municipio.
  • Tema, UF ou nível inválidos levantam InvalidParameterError antes de ler o pacote.
  • MetaInfo:
  • com 1 volume, source_url e raw_content_hash são o PDF do IBGE e o SHA-256 dele;
  • com mais de 1, são o catálogo e o SHA-256 da lista de PDFs.
  • source_method="pacote", from_cache=False; o source_details traz os volumes e a cobertura por página da consulta.
df = await ibge.censo_agro_municipal_1985("efetivo_bovinos", uf="ES")
confirmadas = df[df["valor"].notna()]

temas_censo_agro_municipal_1985 / cobertura_censo_agro_municipal_1985

temas_censo_agro_municipal_1985() lista os 53 temas. cobertura_censo_agro_municipal_1985() dá, por tema, as UFs com casas no pacote.

temas = await ibge.temas_censo_agro_municipal_1985()
cobertura = await ibge.cobertura_censo_agro_municipal_1985()

A CLI tem agrobr ibge temas-municipal-1985 e agrobr ibge censo-municipal-1985 <tema> [--uf] [--nivel] [--formato].


ufs

Lista UFs disponíveis.

async def ufs() -> list[str]

malha_municipal / malha_municipal_geo

Limites municipais da malha territorial do IBGE, edição 2025, em resolução original, pelo WFS dos geoserviços do IBGE (https://geoservicos.ibge.gov.br/geoserverIBGE/wfs, camada CGMAT:qg_2025_030_munic).

async def malha_municipal(
    *,
    uf: str | None = None,
    municipio: str | int | None = None,
    max_registros: int | None = None,
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame | tuple[pd.DataFrame | pl.DataFrame, MetaInfo]

async def malha_municipal_geo(
    *,
    uf: str | None = None,
    municipio: str | int | None = None,
    bbox: tuple[float, float, float, float] | None = None,
    max_registros: int | None = None,
    return_meta: bool = False,
) -> gpd.GeoDataFrame | tuple[gpd.GeoDataFrame, MetaInfo]
  • uf: sigla. municipio: código IBGE de 7 dígitos ou nome inteiro (normalize.resolver_municipio); passe uf junto para desambiguar o nome. Os dois filtros vão ao servidor.
  • bbox (só no _geo): (minlon, minlat, maxlon, maxlat) em EPSG:4326. Devolve os municípios que tocam o retângulo e combina com uf.
  • Colunas: uf, cod_uf (texto, 2 dígitos), cod_municipio (Int64), municipio, area_km2 (float64, a área publicada pelo IBGE). O _geo acrescenta geometry (MultiPolygon, EPSG:4326). Vazio e cheio têm os mesmos dtypes.
  • Lagoas: a camada tem 5.573 feições: os 5.571 municípios e 2 áreas operacionais de lagoas do RS (4300001, Lagoa Mirim, e 4300002, Lagoa dos Patos), que o IBGE publica na malha. Elas saem com uf="RS", com bbox e na malha inteira; por municipio, não, porque não são municípios.
  • Limites: o tabular traz a camada inteira (1,4 MB). O _geo aceita até 900 municípios por consulta: MG, a maior UF, tem 853 (74 MB de GeoJSON, ~17 s em 01/10/2026). Acima do teto, ResourceLimitError antes do download; refine com uf, municipio, bbox ou max_registros. Para o Brasil inteiro em arquivo, a coleta bruta guarda o ZIP nacional da malha (Brasil/BR_Municipios_2025.zip, 237 MB) como o IBGE publica, com o manifesto: bruto.coletar("ibge", "malha_municipal_zip", destino=...). Os ZIPs por UF (UFs/<UF>/<UF>_Municipios_2025.zip) estão no geoftp do IBGE.
  • Páginas originais do WFS: para guardá-las como o IBGE publica, no CRS nativo (EPSG:4674) e com o manifesto, use a coleta bruta: bruto.coletar("ibge", "malha_municipal", ...) ou "areas_urbanizadas".
  • max_registros corta no servidor, na ordem de cd_mun; com ele, coverage["truncated"] fica True quando a seleção é maior.
  • MetaInfo: source="ibge", selected_source ibge_malha_municipal_wfs (_wfs_geo no geo); source_details com layer, edition (2025), query, coverage (a contagem hits sai antes do download e é conciliada com o recebido) e count. Camada corrente: sem ano, inicio nem fim.
municipios = await ibge.malha_municipal(uf="MT")
sinop = await ibge.malha_municipal_geo(municipio="Sinop", uf="MT")
entorno = await ibge.malha_municipal_geo(bbox=(-48.3, -16.1, -47.3, -15.5))

areas_urbanizadas / areas_urbanizadas_geo

Áreas Urbanizadas do Brasil 2022, do IBGE: polígonos mapeados em imagem de satélite, pelo WFS (https://geoservicos.ibge.gov.br/geoserverCGEO/wfs, camada CGEO:AU_2026_AreasUrbanizadas2022_Brasil, 190.172 polígonos).

async def areas_urbanizadas(
    *,
    bbox: tuple[float, float, float, float],
    max_registros: int | None = None,
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame | tuple[pd.DataFrame | pl.DataFrame, MetaInfo]

async def areas_urbanizadas_geo(
    *,
    bbox: tuple[float, float, float, float],
    max_registros: int | None = None,
    return_meta: bool = False,
) -> gpd.GeoDataFrame | tuple[gpd.GeoDataFrame, MetaInfo]
  • bbox obrigatório, (minlon, minlat, maxlon, maxlat) em EPSG:4326: a camada não traz UF nem município. Sem ele, TypeError; com bbox=None, InvalidParameterError.
  • Um município: use o retângulo do limite, tuple((await ibge.malha_municipal_geo(municipio=...)).total_bounds). Ele pega também polígonos vizinhos; para cortar pelo limite, cruze com a geometria do município (geopandas.clip ou geopandas.overlay).
  • Colunas: id (texto, o fid da camada), densidade, tipo e comparacao (texto, como o IBGE publica; no retângulo do DF, densidade é "Densa", "Pouco densa" ou "Loteamento vazio", e comparacao, a mudança desde 2019, traz valores como "Sem alteração", "Adição" e "Densificação"), data_imagem (datetime64[ns], o 1º dia do mês da imagem, publicado como "2022/09"), area_ha e area_km2 (float64). O _geo acrescenta geometry (MultiPolygon, EPSG:4326).
  • Limites: 50.000 polígonos no tabular e 10.000 no _geo por consulta (o retângulo do DF tem 1.083, 1,1 MB de GeoJSON). Acima, ResourceLimitError antes do download. max_registros corta no servidor, na ordem de id (texto).
  • MetaInfo: como na malha, com selected_source ibge_areas_urbanizadas_wfs (_wfs_geo) e edition 2022.
bbox = tuple((await ibge.malha_municipal_geo(municipio="Sinop", uf="MT")).total_bounds)
areas = await ibge.areas_urbanizadas_geo(bbox=bbox)

silvicultura

Obtém dados da Produção da Extração Vegetal e da Silvicultura (PEVS) — silvicultura.

async def silvicultura(
    produto: str,
    ano: int | str | list[int] | None = None,
    *,
    uf: str | None = None,
    nivel: Literal["brasil", "uf", "municipio"] = "uf",
    variavel: str = "quantidade_produzida",
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame

Parâmetros:

Parâmetro Tipo Descrição
produto str Código do produto (ex: 'madeira_tora', 'carvao') ou espécie de área (ex: 'eucalipto')
ano int \| str \| list[int] \| None Ano(s). Default: último disponível
uf str \| None Filtrar por UF (ex: 'MG')
nivel Literal['brasil', 'uf', 'municipio'] Nível: 'brasil', 'uf', 'municipio'
variavel str 'quantidade_produzida', 'valor_producao' (tab 291) ou 'area' (tab 5930)
as_polars bool Retornar como polars.DataFrame
return_meta bool Retornar MetaInfo

Produtos (tab 291, classificação c194):

carvao, carvao_eucalipto, carvao_pinus, carvao_outras, lenha, lenha_eucalipto, lenha_pinus, lenha_outras, madeira_tora, madeira_celulose, madeira_outras_finalidades, acacia_negra, eucalipto_folha, resina

Espécies de área (tab 5930, classificação c734) — variável='area':

eucalipto, pinus, outras

Exemplo:

from agrobr import ibge

# Produção de madeira em tora por UF
df = await ibge.silvicultura('madeira_tora', ano=2023)

# Área plantada de eucalipto
df = await ibge.silvicultura('eucalipto', variavel='area')

# Carvão vegetal em MG
df = await ibge.silvicultura('carvao', ano=2023, uf='MG')

# Com metadados
df, meta = await ibge.silvicultura('madeira_tora', ano=2023, return_meta=True)

produtos_silvicultura

Lista produtos disponíveis na silvicultura (tab 291).

async def produtos_silvicultura() -> list[str]

especies_silvicultura_area

Lista espécies disponíveis para área plantada (tab 5930).

async def especies_silvicultura_area() -> list[str]

extracao_vegetal

Obtém dados da Produção da Extração Vegetal e da Silvicultura (PEVS) — extração vegetal.

async def extracao_vegetal(
    produto: str,
    ano: int | str | list[int] | None = None,
    *,
    uf: str | None = None,
    nivel: Literal["brasil", "uf", "municipio"] = "uf",
    variavel: str = "quantidade_produzida",
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame

Parâmetros:

Parâmetro Tipo Descrição
produto str Código do produto (ex: 'acai', 'castanha_para')
ano int \| str \| list[int] \| None Ano(s). Default: último disponível
uf str \| None Filtrar por UF
nivel Literal['brasil', 'uf', 'municipio'] Nível: 'brasil', 'uf', 'municipio'
variavel str 'quantidade_produzida' ou 'valor_producao'
as_polars bool Retornar como polars.DataFrame
return_meta bool Retornar MetaInfo

Produtos (tab 289, classificação c193):

acai, castanha_caju, castanha_para, erva_mate, mangaba, palmito, pequi_fruto, pinhao, umbu, hevea_coagulado, hevea_liquido, carnauba_cera, carnauba_po, piacava, carvao, lenha, madeira_tora, babacu, copaiba, cumaru, pequi_amendoa

Exemplo:

from agrobr import ibge

# Produção de açaí por UF
df = await ibge.extracao_vegetal('acai', ano=2023)

# Castanha-do-Pará no Amazonas
df = await ibge.extracao_vegetal('castanha_para', ano=2023, uf='AM')

# Valor da produção
df = await ibge.extracao_vegetal('acai', ano=2023, variavel='valor_producao')

# Com metadados
df, meta = await ibge.extracao_vegetal('acai', ano=2023, return_meta=True)

produtos_extracao_vegetal

Lista produtos disponíveis na extração vegetal (tab 289).

async def produtos_extracao_vegetal() -> list[str]

leite_trimestral

Obtém dados da Pesquisa Trimestral do Leite — aquisição, industrialização e preço médio.

async def leite_trimestral(
    trimestre: str | list[str] | None = None,
    *,
    uf: str | None = None,
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame

Parâmetros:

Parâmetro Tipo Descrição
trimestre str \| list[str] \| None Trimestre YYYYQQ (ex: '202303'). Default: último
uf str \| None Filtrar por UF
as_polars bool Retornar como polars.DataFrame
return_meta bool Retornar MetaInfo

Colunas retornadas (pivot wide):

Coluna Tipo Descrição
trimestre str Trimestre YYYYQQ
localidade str UF
localidade_cod int Código IBGE
leite_adquirido float Leite cru adquirido (mil litros)
leite_industrializado float Leite cru industrializado (mil litros)
preco_medio float Preço médio pago ao produtor (R$/litro)
fonte str "ibge_leite_trimestral"

Exemplo:

from agrobr import ibge

# Leite trimestral por UF
df = await ibge.leite_trimestral(trimestre='202303')

# Filtrar por UF
df = await ibge.leite_trimestral(trimestre='202303', uf='MG')

# Múltiplos trimestres
df = await ibge.leite_trimestral(trimestre=['202301', '202302', '202303'])

# Com metadados
df, meta = await ibge.leite_trimestral(trimestre='202303', return_meta=True)

pib_agro

Obtém o PIB agropecuário trimestral (Contas Nacionais Trimestrais).

async def pib_agro(
    setor: str = "agropecuaria",
    *,
    trimestre: str | list[str] | None = None,
    precos: str = "corrente",
    as_polars: bool = False,
    return_meta: bool = False,
) -> pd.DataFrame | pl.DataFrame

Parâmetros:

Parâmetro Tipo Descrição
trimestre str \| list[str] \| None Trimestre YYYYQQ. Default: último
precos str 'corrente' (tab 1846) ou 'real_1995' (tab 6612)
setor str 'agropecuaria', 'industria', 'servicos' ou 'pib_total'
as_polars bool Retornar como polars.DataFrame
return_meta bool Retornar MetaInfo

Exemplo:

from agrobr import ibge

# PIB agropecuário a preços correntes
df = await ibge.pib_agro(trimestre='202501')

# PIB a preços reais (base 1995)
df = await ibge.pib_agro(trimestre='202501', precos='real_1995')

# PIB total (todos os setores)
df = await ibge.pib_agro(trimestre='202501', setor='pib_total')

# Com metadados
df, meta = await ibge.pib_agro(return_meta=True)

Diferenças PAM vs LSPA vs PPM vs Abate vs PEVS vs Leite vs PIB vs Censo Agro vs Série Histórica vs Municipal 1985

Aspecto PAM LSPA PPM Abate PEVS Leite PIB Censo Agro Censo Legado Série Histórica Municipal 1985
Frequência Anual Mensal Anual Trimestral Anual Trimestral Trimestral Decenial Única (1995/96) Decenial Única (1985)
Granularidade Até município Até UF Até município UF Até município UF Brasil Até município Até município Brasil/Região/UF Até município
Tipo Consolidados Estimativas Consolidados Consolidados Consolidados Consolidados Estimativas Censitários Censitários (FTP) Censitários Censitários (OCR)
Disponibilidade T+1 ano T+1 mês T+1 ano T+2 meses T+1 ano T+2 meses T+2 meses Pós-censo Estático Estático Estático (pacote local)
Escopo Lavouras Lavouras Pecuária Abate Silvicultura + Extr. vegetal Leite (aquisição, industrialização) PIB setorial Estrutura agro 6 temas legados 9 temas (1920-2006) 53 temas (1985)

Tabelas SIDRA Utilizadas

Tabela Descrição
5457 PAM - Série desde 1974
6588 LSPA - Estimativas mensais
3939 PPM - Efetivo de rebanhos
74 PPM - Produção de origem animal
1092 Abate - Bovinos
1093 Abate - Suínos
1094 Abate - Frangos
323 Censo Agro 1995 - Efetivo de rebanho
316 / 311 Censo Agro 1995 - Uso da terra
497 / 492 / 503 Censo Agro 1995 - Lavoura temporária
509 / 504 / 510 Censo Agro 1995 - Lavoura permanente
6907 Censo Agro 2017 - Efetivo de rebanho
6881 Censo Agro 2017 - Uso da terra
6957 Censo Agro 2017 - Lavoura temporária
6956 Censo Agro 2017 - Lavoura permanente
791 / 6855 Censo Agro 2006/2017 - Preparo do solo
1249 / 6848 Censo Agro 2006/2017 - Adubação
1245 / 6849 Censo Agro 2006/2017 - Calagem
1459 / 6851 Censo Agro 2006/2017 - Agrotóxicos
837 / 8561 Censo Agro 2006/2017 - Práticas agrícolas
855 / 6857 Censo Agro 2006/2017 - Irrigação
263 Série Histórica - Estabelecimentos e área
264 Série Histórica - Uso da terra
265 Série Histórica - Pessoal e tratores
280 Série Histórica - Condição do produtor
281 Série Histórica - Efetivo de animais
282 Série Histórica - Produção animal
283 Série Histórica - Produção vegetal
1730 Série Histórica - Lavoura permanente
1731 Série Histórica - Lavoura temporária
289 PEVS - Extração vegetal (c193)
291 PEVS - Silvicultura produção (c194)
5930 PEVS - Silvicultura área (c734)
1086 Leite - Pesquisa Trimestral do Leite
1846 PIB - Contas Nacionais a preços correntes
6612 PIB - Contas Nacionais a preços reais (1995)

Versão Síncrona

from agrobr.sync import ibge

df = ibge.pam('soja', ano=2023)
df = ibge.lspa('milho_1', ano=2024, mes=6)
df = ibge.ppm('bovino', ano=2023)
df = ibge.abate('bovino', trimestre='202303')
df = ibge.censo_agro('efetivo_rebanho')
df = ibge.censo_agro('preparo_solo', ano=2017)
df = ibge.censo_agro_legado('tecnologia')
df = ibge.censo_agro_legado('pessoal_ocupado', uf='SP')
df = ibge.censo_agro_historico('estabelecimentos_area', ano=1985)
temas_1985 = ibge.temas_censo_agro_municipal_1985()
df = ibge.silvicultura('madeira_tora', ano=2023)
df = ibge.extracao_vegetal('acai', ano=2023)
df = ibge.leite_trimestral(trimestre='202303')
df = ibge.pib_agro(trimestre='202501')

Notas

  • Consultas por município geram grande volume de dados
  • Recomenda-se filtrar por UF quando usar nível município
  • LSPA é atualizado mensalmente pelo IBGE
  • PAM é consolidada anualmente após colheita
  • PPM é consolidada anualmente (setembro), série desde 1974
  • Abate Trimestral disponível desde 1997, atualizado a cada trimestre (T+2 meses)
  • Censo Agropecuário: 11 temas, dados de 1995, 2006 e/ou 2017 conforme disponibilidade. Referência 2017: out/2016 a set/2017
  • Censo Agropecuário Legado: 6 temas FTP (tecnologia, pessoal_ocupado, maquinas, producao_animal, valor_producao, financeiro). Ano fixo 1995
  • Série Histórica: 9 temas, 1920-2006, até UF (municipal NÃO disponível). Unidades mistas por categoria (Aves=Mil cabeças, etc)
  • Censo Municipal 1985: 53 temas (tabelas 67 a 119), 27 UFs, casa a casa, num pacote local; valor só na casa confirmada pelas somas impressas e valor_lido sempre, com o status de cada casa (contrato 2.0)

Unidades e quebras históricas da PAM

Os valores publicados não são convertidos implicitamente. unidade_producao, unidade_rendimento e unidade_valor_producao identificam a escala de cada linha. Laranja anterior a 2001 usa mil_frutos e frutos/ha; desde 2001, ton e kg/ha. condicao_produto distingue café em_coco até 2001 e beneficiado desde 2002. As moedas históricas permanecem identificadas, sem conversão para reais nem correção de inflação. Consulte as notas metodológicas do IBGE.

localidade_cod (contrato producao_anual 2.2) traz o código IBGE da localidade como o SIDRA publica (D1C): 7 dígitos no município, 2 na UF e 1 no Brasil. Use-o para juntar municípios entre anos, porque o nome publicado muda (e o do DF sai como "Brasília (DF)", sem o " - UF" dos demais). No producao_anual, só as linhas do IBGE trazem o código; o fallback da CONAB não.

O símbolo SIDRA - significa zero numérico e é preservado como zero; .., ... e X permanecem ausentes. Municípios com produção zero não são eliminados. O contrato producao_anual é 2.2; as quatro colunas descritivas e o localidade_cod são opcionais no contrato e entregues pela API PAM.

O parser PAM 2 preserva também localidades e medidas inteiramente ausentes ou suprimidas. Duas observações para a mesma localidade, ano e medida, inclusive aliases de variável que colidem, geram ParseError; variáveis sem mapeamento também são recusadas. Não há seleção silenciosa do primeiro valor. O schema da API PAM é o do contrato producao_anual, 2.2 (meta.schema_version); a API entrega as 14 colunas, sem o cod_municipio, que só o dataset producao_anual acrescenta.

Nas APIs PEVS, variavel="valor_producao" preserva a unidade monetária publicada em unidade e retorna valor como float64, mesmo quando todos os valores são inteiros. O parser é 2; os contratos de silvicultura e extrativismo estão em 1.1.

As APIs trimestrais de abate, leite e PIB usam parser 2. No abate, - representa zero, enquanto X e ... continuam nulos; peso disponível é preservado mesmo sem a observação de cabeças. Abate e leite rejeitam observações duplicadas na mesma variável, trimestre e localidade antes do cruzamento. preco_medio do leite e valor do PIB usam float64, inclusive quando todos os valores são inteiros.

O censo SIDRA atual usa parser 3, que publica a linha Total da fonte, e o histórico usa parser 2. Nos dois, - representa zero, e X/... continuam nulos. A chave ano/localidade/tema/categoria/variável deve ser única, inclusive entre tabelas complementares. No preparo do solo com variável como categoria, o ano da resposta é preservado quando informado; o ano da tabela só é usado quando essa dimensão está ausente.