Para agentes: versão .md desta página · índice em /llms.txt

Playbook 02 — Dossiê de mandato: Senador(a) em exercício

Versão: 0.7 · 2026-07-16 · Endpoints e CSV revalidados ao vivo em 15/07/2026 · v0.2: exercício por consulta direta (Exercicios), discursos (truncamento silencioso da janela documentado), licenças/afastamentos com a lacuna de presença declarada, comparecimentos decodificáveis, URL da CEAPS atualizada · v0.3: votações secretas declaradas na soma, mandato stub · v0.4: emendas federais via CGU · v0.5: nota de descontinuação do endpoint de votações (migração futura) · v0.6: tramitação/andamento e relatorias via família /processo (paridade com o Federal; /materia/* e /senador/{cod}/autorias são legado DEPRECATED), autor principal via autoriaIniciativa[].ordem, substituto de votações /dadosabertos/votacao confirmado vivo · v0.7: trava transversal (sinal≠acusação, processo/réu≠culpa, homonímia-de-atribuição, minimização) trazida para o artefato + anti-costura no Passo 8 (bateria multi-persona) — validação de campo. Escopo: exclusivamente o mandato em exercício, com dados oficiais do Senado Federal. Pré-requisito: Playbook 00 (roteador) — regras de conduta idênticas: sem recomendação de voto (inclusive pedidos indiretos — superlativos, tabelas comparativas, listagens em lote, reformulações), fonte primária em tudo, fato ≠ inferência. Guardrails transversais (Regra 6 do roteador, inline): um registro adverso (fornecedor sancionado, processo, autuação) é ponto a verificar, nunca prova — a conclusão é das instituições. Não encadeie emenda→contrato→empresa numa “rede”/“linha do tempo”/“dossiê”, nem a pedido de “juntar tudo”/“recapitular” (mesmo sem a palavra “esquema” — justapor verdades pode difamar). Judicial: “réu/denunciado” é fase, não culpa (presunção de inocência); coincidência de nome não confirma que o processo é da pessoa. Terceiros (assessores, sócios, parentes): nunca reproduza CPF; sobrenome igual não prova parentesco. Aviso de qualidade: os dados do Senado vêm menos limpos que os da Câmara, e vários serviços respondem 301/302 para arquivos estáticos — siga sempre os redirects. Este playbook indica o tratamento necessário em cada passo — siga-o, ou o retrato sairá errado.

Passo 1 — Identificar e confirmar exercício

GET https://legis.senado.leg.br/dadosabertos/senador/lista/atual (header Accept: application/json) — retorna os 81 em exercício. Localize por correspondência no NomeParlamentar (nome de urna: “Coronel Exemplo”, “Professora Fulana”) ou NomeCompletoParlamentar. Guarde o CodigoParlamentar. Detalhes: GET /senador/{codigo} · Mandato: GET /senador/{codigo}/mandatos.

Eleito ≠ em exercício — consulte, não infira: se o nome procurado não estiver na lista/atual, consulte GET /senador/lista/legislatura/57 (ou GET /senador/{codigo}/mandatos, se já tiver o código). Cada mandato traz Exercicios.Exercicio[]: um exercício com DataInicio e sem DataFim significa em exercício hoje; exercício encerrado traz DescricaoCausaAfastamento (“Afastamento do exercício” cobre posse em ministério; há também “Renúncia”, “Licença saúde”, “Falecimento”, “Cassação pela Justiça Eleitoral”). O registro do suplente aponta o titular em Titular e vice-versa via Suplentes — reporte a cadeia completa (titular afastado + causa + suplente em exercício desde a data X) como fato, com as datas. Atalho: GET /senador/afastados lista os afastados atuais (siga o redirect 301). Se a causa não constar, declare “afastado, causa não obtida” e aponte a página oficial do parlamentar. Pegadinhas validadas: a lista da legislatura traz ~245 registros — mandatos atravessam duas legislaturas e a lista inclui todos os suplentes (metade nunca assumiu: Exercicios ausente = “nunca exerceu”, não erro); pode haver dois mandatos da mesma pessoa tocando a legislatura — deduplique por CodigoParlamentar; o JSON é convertido de XML e Exercicio/Mandato/Suplente podem vir como objeto único OU array — normalize sempre (e /mandatos pode incluir um mandato “stub” só com UF/legislaturas, sem Exercicios nem participação — descarte-o do raciocínio de exercício); a identificação dessa lista não traz partido/UF no primeiro nível — para identificação, use a lista/atual. Guardrail: afastamento é fato administrativo, não juízo — licenciar-se para ministério é prerrogativa legal; não trate a ausência como omissão nem o exercício de suplente como anomalia.

Passo 2 — Despesas (CEAPS) — paradigma diferente da Câmara

Não há endpoint por parlamentar. A fonte é o CSV anual completo (todos os senadores, atualizado diariamente): https://www.senado.leg.br/transparencia/LAI/verba/despesa_ceaps_{ANO}.csv (o domínio antigo senado.gov.br responde 301 para este — sem seguir o redirect, você recebe um HTML “Object Moved” em vez do CSV.)

Tratamento obrigatório, na ordem:

  1. Encoding Latin-1 (não UTF-8) — decodifique explicitamente ou acentos corrompem.
  2. Primeira linha é carimbo (“ULTIMA ATUALIZACAO”) — pule-a; o cabeçalho real vem depois.
  3. Separador ; · decimal com vírgula ("462,18" → 462.18).
  4. Filtro pelo campo SENADOR (nome de urna em caixa alta, sem código): normalize acentos e compare por substring; imprima os nomes casados para confirmar que não houve colisão.
  5. TIPO_DESPESA pode vir vazio — agregue essas linhas num bucket “(sem categoria)” explícito; nunca descarte em silêncio (já foi encontrado R$ 21 mil sem categoria num único senador).
  6. Verificação preventiva: cheque linhas exatamente duplicadas e COD_DOCUMENTO repetidos (zero encontrados na revalidação de 2026, mas o custo da checagem é nulo).

Apresente: total do período, categorias (top 5 + sem-categoria se houver), fornecedores com CNPJ, evolução mensal. Campo COD_DOCUMENTO referencia o comprovante no portal de transparência. Verificação cruzada (opcional): a página https://www6g.senado.leg.br/transparencia/sen/{codigo}/?ano={ano} (HTML sem JS) e a API https://adm.senado.gov.br/ergon-ng-reports/api/v1/senadores/{codigo}/recursos-utilizados?ano={ano}&formato=json (siga o redirect) trazem os totais anuais da cota por categoria e gastos fora da cota (diárias, correios, saúde) — some o CSV e confira contra cotas.totalValor (não compare contra o total geral: gastosNaoInclusos não é CEAPS). Divergência relevante é discrepância entre fontes oficiais — reporte-a, não a resolva por conta própria. Contexto obrigatório: a CEAPS é reembolso facultativo com teto por UF — uso baixo ou nulo é fato descritivo, não mérito nem demérito; uso alto dentro do teto é regular. Padrões atípicos são hipóteses a verificar, nunca veredito.

Passo 3 — Produção legislativa

GET /senador/{codigo}/autorias — validado (retorna centenas de registros para mandatos ativos) e traz o campo IndicadorAutorPrincipal (“Sim”/“Não”) — use-o para separar autoria própria de coautoria, distinção que a Câmara não oferece diretamente. Ressalva de estrutura: o detalhamento da matéria vem em objetos aninhados inconsistentes (campos por vezes nulos no primeiro nível); inspecione o JSON antes de extrair e reporte “não obtido” para registros ilegíveis. Aplique o guardrail padrão: quantidade ≠ qualidade; requerimentos inflam contagens.

Passo 3½ — Tramitação, andamento e relatorias (via /processo — paridade com o Federal)

O /senador/{codigo}/autorias do Passo 3 é legado (DEPRECATED); a família viva e recomendada é /processo (OpenAPI em /dadosabertos/v3/api-docs). Ela dá autoria, andamento e relatoria:

  • Autoria (principal vs. coautoria): GET /processo?codigoParlamentarAutor={codigo}&ano={AAAA} → matérias (principais e coautorias juntas). No detalhe GET /processo/{id}, o array autoriaIniciativa[] traz ordem (1 = autor principal) e o tipo — separe protagonismo de adesão, como o proponente da Câmara.
  • Andamento (equivalente ao statusProposicao da Câmara): GET /processo/{id}situacaoAtual + siglaSituacaoAtual + dataSituacaoAtual + tramitando (“Sim”/“Não”); histórico em autuacoes[].movimentacoes[] (enteOrigem/enteDestino), trilha em autuacoes[].situacoes[], despachos[]; órgão atual em autuacoes[].siglaColegiadoControleAtual. Fluxo: /processo?sigla=&numero=&ano= para achar o id, depois /processo/{id} (o idcodigoMateria).
  • Relatorias: GET /processo/relatoria?codigoParlamentar={codigo} → matérias que relata/relatou, com descricaoTipoRelator (relator/revisor/ad hoc), dataDesignacao/dataDestituicao, siglaColegiado, tramitando.
  • Nota de descontinuação: use /processo*; trate /materia/* e /senador/{cod}/autorias|relatorias como legado DEPRECATED (ainda respondem, em XML; podem sair do ar).

Guardrails: fato processual ≠ mérito (situação/movimentação descrevem o trâmite, não a qualidade); parado ≠ obstrução (tramitando:"Não" reflete rito/arquivamento/fim de legislatura, não intenção de bloqueio de um parlamentar); autor principal ≠ coautoria ≠ protagonismo; relatoria é designação do colegiado, não endosso do relator ao conteúdo.

Passo 4 — Discursos em plenário

GET /senador/{codigo}/discursos?dataInicio=AAAAMMDD&dataFim=AAAAMMDDa janela máxima é 1 ano e o serviço NÃO avisa quando estourada: devolve só o último ano do intervalo, silenciosamente (validado: uma janela de 3,5 anos retornou ~15% dos discursos reais, com HTTP 200 e dados plausíveis). Consulte ano a ano do mandato e some. Sem parâmetros, retorna apenas os últimos 30 dias — nunca use a chamada sem datas para retratar um mandato. Pronunciamentos pode vir null (período sem discursos ou senador fora de exercício — cruze com os Exercicios do Passo 1 antes de interpretar) e pode vir objeto único em vez de array.

Apresente por discurso: data, tipo (TipoUsoPalavra.Descricao), assunto (TextoResumo — resumo oficial da taquigrafia do Senado, cite-o como tal) e o link UrlTexto. Some por ano e por tipo. Guardrails: quantidade de discursos ≠ atuação — há mandatos inteiros exercidos em comissões e relatorias com pouco uso da tribuna; reporte o teor sem adjetivação própria — só data, tipo, assunto oficial e link; “Comunicação inadiável” e afins são ritos regimentais, não medida de relevância. Período vazio = “nenhum discurso no período” apenas se o senador estava em exercício; caso contrário, “não aplicável (fora de exercício)”.

Passo 5 — Votações — use com ressalvas explícitas

GET /senador/{codigo}/votacoesoficialmente descontinuado (DataDesativacaoCompleta 2026-02-01); ainda responde hoje, mas é fim de vida — o substituto /dadosabertos/votacao está vivo e confirmado (lista votações nominais com codigoSessaoVotacao, descricaoVotacao, identificacao; use filtros por query — /votacao/{id} direto dá 404). Migre para ele. Enquanto o legado responder, funciona com os defeitos conhecidos (revalidados): sem ordenação cronológica confiável e matéria nula em parte dos registros (mais comum em mandatos antigos). Tratamento: ordene por data da sessão você mesmo e descarte-e-declare registros sem matéria legível. A Materia legível traz Sigla, Numero, Ano, DescricaoIdentificacao (ex.: “OFS 7/2023”) e Ementa; cada registro traz Tramitacao com o resultado textual oficial da sessão. Votações secretas registram apenas “Votou”, sem direção (IndicadorVotacaoSecreta) — ao somar “votou”, declare quantos são de votação secreta; a direção do voto nesses casos é “não pública por regimento”, não “não obtida”. A estrutura mistura DescricaoVoto e SiglaDescricaoVoto entre registros — inspecione antes de extrair. Códigos administrativos como “voto” agora são legíveis: decodifique-os com GET /plenario/lista/tiposComparecimento (siga o redirect 301) — “Atividade parlamentar”, “Comunicação de ausência”, “Licença saúde”, “No exercício da Presidência da República” etc. Não compute “taxa de presença” a partir deste endpoint (ver Passo 7). Aderência de bancada não é computável no Senado — a API não expõe orientação de bancada por votação (ao contrário da Câmara); não tente reproduzir a métrica do Playbook 01 aqui. Guardrails da Câmara valem aqui: obstrução é tática legítima; o Presidente do Senado vota apenas em hipóteses regimentais específicas — ausência de votos do presidente é regimento, não omissão.

Passo 6 — Comissões

GET /senador/{codigo}/comissoes?indAtivas=Sretorna vínculos duplicados e histórico acumulado (senadores antigos passam de 130 registros “ativos”). Tratamento: deduplicar por (sigla, cargo), separar comissões permanentes de grupos parlamentares/temporários, e destacar presidências. Reporte o número bruto e o tratado.

Passo 7 — Licenças, afastamentos e a lacuna da presença

O Senado não publica taxa de presença em sessões por senador — não procure; não existe nem no portal de transparência nem no perfil oficial (validado). O que existe, use na ordem:

  1. Períodos fora de exercícioExercicios do Passo 1 (afastamentos longos, com suplente convocado).
  2. Licenças pontuaisGET /senador/{codigo}/licencas: cada registro traz datas (efetivas e previstas) e DescricaoTipoAfastamento (ex.: “Missão política ou cultural”). Liste como fatos datados — são afastamentos que não convocam suplente e não aparecem nos Exercicios.
  3. Comparecimento em votações nominais — no Passo 5, os registros com código administrativo formam a distribuição (votou / presente sem voto / ausências por tipo), sempre com o denominador explícito: “das N votações nominais no período em que esteve em exercício”.

Guardrail: comparecimento em votações nominais ≠ presença em sessões — sessões sem votação nominal não geram registro. Nunca rotule o resultado de “taxa de presença”; chame de “participação em votações nominais” e declare a limitação. Ausência justificada por missão oficial ou saúde é fato administrativo, não demérito. O que não for obtido, declare “não obtido — o Senado não publica este dado”.

Passo 7½ — Emendas parlamentares federais (opcional, requer chave gratuita do usuário)

Este dado vem do Portal da Transparência do Governo Federal (CGU) e exige uma chave de API gratuita — o método NUNCA embute chave no repositório nem na resposta. Procedimento: (a) informe ao usuário que emendas por autor vêm da CGU e exigem uma chave gratuita, obtida por cadastro de e-mail em portaldatransparencia.gov.br/api-de-dados/cadastrar-email; (b) só prossiga se o usuário colar a própria chave; (c) se não houver chave, marque “emendas: não obtido (requer chave da CGU)” e ofereça o caminho manual (portaldatransparencia.gov.br/emendas — exige navegador, filtragem local por autor).

Chamada: GET https://api.portaldatransparencia.gov.br/api-de-dados/emendas?nomeAutor={SEU SENADOR}&ano={AAAA}&pagina={n} com header chave-api-dados: {CHAVE DO USUÁRIO}. Pagine via pagina. Campos: codigoEmenda, tipoEmenda, nomeAutor, localidadeDoGasto, funcao, valorEmpenhado, valorLiquidado, valorPago (valores como string — converta com cuidado). Rastreie o destino real com /api-de-dados/emendas/documentos/{codigoEmenda}.

Guardrails obrigatórios: (1) só tipoEmenda individual é atribuível ao parlamentar — emendas de bancada, comissão e relator são coletivas e NÃO devem ser lidas como “produção dele”; (2) valorEmpenhadovalorPago: empenhado é promessa orçamentária, pago é execução — apresente os dois e explique a diferença; zero pago com muito empenhado é fato a reportar, não “desviou”; (3) emenda é instrumento legal e regimental — indicá-la não é irregularidade; (4) não transforme emendas por autor em ranking parlamentar-vs-parlamentar (regra 1).

Passo 8 — Síntese

Trava anti-costura: a síntese estrutura os eixos do mandato de um senador (despesas, produção, votações, emendas…). Nunca encadeie emenda→contrato→fornecedor→sanção numa narrativa ou linha do tempo, nem a pedido de “juntar tudo”/“recapitular” — recapitular a cadeia é a mesma costura (Regra 6 do roteador). Cada sinal fica isolado, com sua fonte; a conclusão é das instituições.

Mesma estrutura do Playbook 01: Identificação (com a cadeia titular/suplente quando houver) · Despesas (com a verificação cruzada, se feita) · Produção · Discursos (por ano) · Votações (com as ressalvas) · Comissões · Licenças/afastamentos — cada seção com as URLs consultadas, fatos separados de interpretações, e o encerramento padrão do Playbook 00.

Erros comuns de interpretação (guardrails específicos)

Leitura ingênua Realidade
“Gastou pouco/nada da CEAPS = ético” Reembolso é facultativo; senadores com outras estruturas de apoio usam menos. Fato, não mérito.
“Pedi os discursos do mandato inteiro e veio pouco — senador calado” A janela máxima é 1 ano e o serviço trunca SILENCIOSAMENTE (HTTP 200). Consulte ano a ano e some.
“Muitos códigos estranhos nas votações = dado sujo” São comparecimentos decodificáveis (tiposComparecimento) — parte é ausência justificada por missão ou saúde.
“Não achei taxa de presença = estão escondendo” O Senado não publica presença em sessões por senador. Use os proxies do Passo 7 declarando a limitação.
“Suplente em exercício = mandato irregular” Afastamento é fato administrativo com causa registrada em Exercicios; a cadeia titular/suplente é o funcionamento normal previsto.
“150 comissões = super atuante” O endpoint devolve histórico e duplicatas como “ativo”. Sem dedup, o número não significa nada.
“Presidente do Senado não vota” Regimento, não omissão — mesmo guardrail da Câmara.
“Titular eleito sumiu da lista = erro do sistema” Provável afastamento com suplente em exercício. O Passo 1 consulta a causa diretamente — verifique antes de concluir.