Voltar ao início

API do BID do Avaí

Uma API pública de leitura sobre os registros do Avaí Futebol Clube no BID (Boletim Informativo Diário) da CBF, de 2003-01-01 até hoje. Tudo em JSON, com chave de API. Esta página é a referência completa: endpoints, parâmetros, exemplos prontos para copiar, dicionário de dados e os cuidados necessários para não interpretar o BID errado.

O que é esta API e de onde vem o dado

O BID é o diário oficial do futebol brasileiro: é nele que a CBF publica os registros de contrato dos atletas. Sem isso, ninguém entra em campo. Este site acompanha o que o BID publica sobre o Avaí Futebol Clube (clube 20058 no BID) e guarda tudo, desde 2003-01-01 até hoje.

A única fonte é o BID da CBF. Não há dado de imprensa, de site de transferências nem de redes sociais. Se não saiu no BID, não está aqui.

  • Um monitor consulta o BID a cada 20 minutos e grava as publicações novas (essas ficam com origem: "monitor").
  • Uma rotina de mineração percorre o passado dia a dia desde 2003-01-01 para recuperar o histórico (origem: "historico"). O progresso aparece em /estatisticas.
  • Uma consulta diária por atleta pergunta ao BID onde cada pessoa está registrada hoje. É a única forma de saber quem o clube emprestou para fora.

A URL base é https://bid.avaifc.com/api/v1. Todos os endpoints são GET e respondem JSON com charset=utf-8.

Autenticação

Uma chave por aplicação. A chave identifica você no limite de requisições.

Mande sua chave em um dos dois cabeçalhos — escolha o que for mais fácil no seu cliente:

Authorization: Bearer SUA_CHAVE
X-API-Key: SUA_CHAVE

Sem chave, ou com uma chave errada, a resposta é 401 com o código nao_autenticado. Os endpoints /saude e /openapi.json são abertos e não pedem chave.

Como pedir uma chave: fale com quem mantém o site — pelo próprio site ou pelo canal do projeto no Telegram — dizendo para que você vai usar e qual volume espera. As chaves são nominais e podem ser revogadas.

Nunca exponha a chave no navegador

Não coloque a chave em JavaScript de página, aplicativo móvel ou qualquer código que o usuário final possa ler: quem abrir o DevTools copia a sua chave. Chame esta API do seu servidor e repasse o resultado para o seu front-end. O CORS está liberado para facilitar testes e protótipos, não para você embutir a chave em produção.

Limites e cache

  • 600 requisições por 1 minuto por chave. Sem chave válida, o limite é de 120 por minuto por IP.
  • Cada resposta traz X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset (momento em que a janela reinicia, em segundos desde a época Unix).
  • Ao estourar: 429 com o código limite_excedido e o cabeçalho Retry-After em segundos. Espere o tempo indicado em vez de insistir.
  • Respostas de sucesso vêm com Cache-Control: public, max-age=60, stale-while-revalidate=120. Pode cachear por 60 segundos sem medo: o monitor só roda a cada 20 minutos.
  • Access-Control-Allow-Origin: *, então dá para chamar do navegador em testes.

Se você precisa varrer o acervo inteiro, use limit=100 com paginação por cursor e guarde o resultado do seu lado: é mais rápido para você e mais leve para o servidor do que repetir a mesma consulta.

Formato de erro

Todo erro da API — qualquer endpoint, qualquer status — tem o mesmo corpo:

{
  "erro": {
    "codigo": "parametro_invalido",
    "mensagem": "Parâmetro \"limit\" inválido: esperado um número inteiro entre 1 e 100.",
    "detalhes": {
      "parametro": "limit",
      "valor": "500",
      "esperado": "um número inteiro entre 1 e 100"
    }
  }
}

codigo é estável e serve para o seu código tratar o erro; mensagem é texto para humanos e pode mudar; detalhes é opcional.

CódigoHTTPQuando acontece
api_nao_configurada503O servidor está sem nenhuma chave configurada. Nada a fazer do lado de quem chama.
nao_autenticado401Chave ausente, com erro de digitação ou revogada.
parametro_invalido400Algum parâmetro saiu do formato ou da faixa aceita. detalhes diz qual e o que era esperado.
nao_encontrado404Código de atleta desconhecido ou fora do formato.
limite_excedido429Você passou do limite de requisições por minuto.
erro_interno500Falha nossa ao consultar o banco. Tente de novo em instantes.

Paginação por cursor

Em /registros, pagine por cursor: chame sem cursor, leia paginacao.proximoCursor e repita passando aquele valor em ?cursor= até receber null. O cursor é opaco — não tente decodificá-lo, o formato pode mudar.

Por que não usar offset: o histórico ainda pode estar sendo minerado, e registros antigos entram no meio da lista. Com offset isso desloca as páginas seguintes e você acaba repetindo ou perdendo itens. O cursor fixa a posição pelo par (data de publicação, registro), então a varredura é consistente. offset continua existindo para casos simples e é ignorado quando há cursor.

import os, requests

chave = os.environ["BID_API_KEY"]
cursor, todos = None, []
while True:
    r = requests.get(
        "https://bid.avaifc.com/api/v1/registros",
        params={"limit": 100, **({"cursor": cursor} if cursor else {})},
        headers={"Authorization": f"Bearer {chave}"},
        timeout=30,
    )
    r.raise_for_status()
    pagina = r.json()
    todos.extend(pagina["registros"])
    cursor = pagina["paginacao"]["proximoCursor"]
    if not cursor:
        break

print(len(todos), "registros")

Em /atletas a paginação é por page simples, porque a lista é bem menor e ordenada por atividade recente.

Referência dos endpoints

Todos são GET e respondem JSON.

GET/api/v1/registroschave obrigatória

Cada item é um registro publicado no BID: uma linha que a CBF divulgou para um atleta do clube em uma data. É a base de tudo no site. A lista aceita filtros por período, atleta, tipo exato e categoria, e pagina por cursor.

Parâmetros

ParâmetroTipoPadrãoDescrição
ordemenumrecentesOrdenação por data de publicação.

Valores aceitos: recentes · antigos

limitinteiro25Quantos itens trazer por página.

Faixa: 1 a 100.

Exemplo: 50

cursorstring—Cursor de paginação devolvido em paginacao.proximoCursor. Com cursor, registros inseridos no meio da mineração do histórico não deslocam a página seguinte.

Exemplo: eyJkIjoiMjAyNC0wMS0zMSAxNDoyMDowMCIsImsiOiJhYmMifQ

offsetinteiro0Paginação simples por deslocamento. Ignorado quando cursor é enviado.

Faixa: 0 a 10000000.

desdedata—Só registros publicados nesse dia ou depois (data_publicacao).

Exemplo: 2024-01-01

atedata—Só registros publicados até esse dia, incluindo o dia inteiro.

Exemplo: 2024-12-31

atletastring—Código CBF do atleta (codigo_atleta).

Exemplo: 123456

tipostring—tipo_contrato exato, sem diferenciar maiúsculas nem acentos. Use quando você quer um status específico do BID, e não um agrupamento.

Exemplo: Contrato Definitivo

categoriaenum—Agrupamento dos tipos do BID feito pelo site (um tipo cai na primeira regra que casa). Útil porque o BID usa dezenas de redações diferentes para a mesma coisa.

Valores aceitos: contratacao · rescisao · emprestimo · renovacao · base · liberacao · transferencia · outros

Exemplo: contratacao

Exemplo de requisição

curl -s -H "Authorization: Bearer $BID_API_KEY" \
  "https://bid.avaifc.com/api/v1/registros?limit=2&categoria=contratacao"

Exemplo de resposta

{
  "registros": [
    {
      "record_key": "9f1c0f4e8d3b2a17c5e6d7b8a9f0c1d2e3f40516",
      "codigo_atleta": "742193",
      "nome": "JOAO PEDRO DA SILVA SANTOS",
      "apelido": "Joao Pedro",
      "tipo_contrato": "Contrato Definitivo",
      "id_contrato": "1842655",
      "contrato_numero": "2024/0137",
      "data_publicacao": "2024-07-18 15:42:00",
      "data_inicio": "2024-07-17",
      "data_termino": "2026-12-31",
      "data_nascimento": "2001-03-24",
      "sexo": "1",
      "codigo_clube": "20058",
      "clube": "Avaí Futebol Clube",
      "uf": "SC",
      "origem": "monitor",
      "first_seen_at": "2024-07-18T19:00:11.482Z",
      "notified_at": "2024-07-18T19:00:14.093Z"
    },
    {
      "record_key": "2b7d5a1e9c8f3046b2a1d5e7f8c9b0a1d2e3f405",
      "codigo_atleta": "688204",
      "nome": "CARLOS EDUARDO PEREIRA",
      "apelido": "Cadu",
      "tipo_contrato": "Transferencia Definitiva",
      "id_contrato": "1790322",
      "contrato_numero": "2024/0092",
      "data_publicacao": "2024-04-02 11:08:00",
      "data_inicio": "2024-04-01",
      "data_termino": "2025-12-31",
      "data_nascimento": "1998-11-02",
      "sexo": "1",
      "codigo_clube": "20058",
      "clube": "Avaí Futebol Clube",
      "uf": "SC",
      "origem": "historico",
      "first_seen_at": "2025-02-11T03:21:45.117Z",
      "notified_at": null
    }
  ],
  "paginacao": {
    "limit": 2,
    "total": 184,
    "temMais": true,
    "proximoCursor": "eyJkIjoiMjAyNC0wNC0wMiAxMTowODowMCIsImsiOiIyYjdkNWExZTljOGYzMDQ2YjJhMWQ1ZTdmOGM5YjBhMWQyZTNmNDA1In0"
  },
  "filtros": {
    "ordem": "recentes",
    "desde": null,
    "ate": null,
    "atleta": null,
    "tipo": null,
    "categoria": "contratacao"
  }
}

total é o número de registros que casam com os filtros, não o tamanho da página.

Para varrer tudo, repita a chamada com cursor = paginacao.proximoCursor até receber null.

GET/api/v1/atletaschave obrigatória

Enquanto /registros tem uma linha por publicação, aqui cada item é um atleta: quantos registros ele tem, quando apareceu pela primeira e pela última vez, o status do registro mais recente e — quando a consulta diária por atleta já rodou — onde ele está registrado hoje.

Parâmetros

ParâmetroTipoPadrãoDescrição
buscastring—Procura por nome, apelido ou código, sem diferenciar maiúsculas nem acentos. O atleta entra na lista quando qualquer registro dele casa.

Exemplo: joao

pageinteiro1Página (1 é a primeira).

Faixa: 1 a 100000.

limitinteiro25Quantos itens trazer por página.

Faixa: 1 a 100.

Exemplo: 50

Exemplo de requisição

curl -s -H "Authorization: Bearer $BID_API_KEY" \
  "https://bid.avaifc.com/api/v1/atletas?busca=joao&limit=1"

Exemplo de resposta

{
  "atletas": [
    {
      "codigo_atleta": "742193",
      "nome": "JOAO PEDRO DA SILVA SANTOS",
      "apelido": "Joao Pedro",
      "data_nascimento": "2001-03-24",
      "idade": 25,
      "sexo": "1",
      "totalRegistros": 4,
      "primeiroRegistro": "2019-02-08 10:15:00",
      "ultimoRegistro": "2024-07-18 15:42:00",
      "ultimoTipo": "Contrato Definitivo",
      "situacaoAtual": {
        "clube_codigo": "20058",
        "clube_nome": "Avai Futebol Clube",
        "tipo_contrato": "Contrato Definitivo",
        "desde": "2024-07-17"
      },
      "url": "https://bid.avaifc.com/players/742193"
    }
  ],
  "paginacao": { "page": 1, "limit": 1, "total": 3, "totalPaginas": 3 },
  "filtros": { "busca": "joao" }
}

situacaoAtual vem da consulta diária por atleta e pode apontar outro clube (empréstimo para fora).

idade é calculada no fuso de Brasília; é null quando o BID não traz data de nascimento.

GET/api/v1/atletas/{codigo}chave obrigatória

A ficha completa de uma pessoa: o mesmo resumo da listagem, todos os registros dela no BID (do mais novo para o mais antigo), a última consulta diária do BID por atleta — inclusive jogos por categoria nos últimos 12 meses — e, se ela está no elenco atual, em qual grupo e categoria.

Parâmetros

ParâmetroTipoPadrãoDescrição
codigostring (caminho)—Código CBF do atleta. Código desconhecido ou fora do formato responde 404.

Exemplo: 742193

Exemplo de requisição

curl -s -H "Authorization: Bearer $BID_API_KEY" \
  "https://bid.avaifc.com/api/v1/atletas/742193"

Exemplo de resposta

{
  "atleta": {
    "codigo_atleta": "742193",
    "nome": "JOAO PEDRO DA SILVA SANTOS",
    "apelido": "Joao Pedro",
    "data_nascimento": "2001-03-24",
    "idade": 25,
    "sexo": "1",
    "totalRegistros": 4,
    "primeiroRegistro": "2019-02-08 10:15:00",
    "ultimoRegistro": "2024-07-18 15:42:00",
    "ultimoTipo": "Contrato Definitivo",
    "situacaoAtual": {
      "clube_codigo": "20058",
      "clube_nome": "Avai Futebol Clube",
      "tipo_contrato": "Contrato Definitivo",
      "desde": "2024-07-17"
    },
    "url": "https://bid.avaifc.com/players/742193"
  },
  "registros": [
    {
      "record_key": "9f1c0f4e8d3b2a17c5e6d7b8a9f0c1d2e3f40516",
      "codigo_atleta": "742193",
      "nome": "JOAO PEDRO DA SILVA SANTOS",
      "apelido": "Joao Pedro",
      "tipo_contrato": "Contrato Definitivo",
      "id_contrato": "1842655",
      "contrato_numero": "2024/0137",
      "data_publicacao": "2024-07-18 15:42:00",
      "data_inicio": "2024-07-17",
      "data_termino": "2026-12-31",
      "data_nascimento": "2001-03-24",
      "sexo": "1",
      "codigo_clube": "20058",
      "clube": "Avaí Futebol Clube",
      "uf": "SC",
      "origem": "monitor",
      "first_seen_at": "2024-07-18T19:00:11.482Z",
      "notified_at": "2024-07-18T19:00:14.093Z"
    }
  ],
  "situacaoBid": {
    "clube_codigo": "20058",
    "clube_nome": "Avai Futebol Clube",
    "tipo_contrato": "Contrato Definitivo",
    "contrato_numero": "2024/0137",
    "data_inicio": "2024-07-17",
    "data_publicacao": "2024-07-18 15:42:00",
    "jogos_total": 96,
    "jogos_pelo_clube_12m": 31,
    "ultimo_jogo_data": "2026-09-20",
    "ultimo_jogo_categoria": "Série B",
    "ultimo_jogo_campeonato": "Campeonato Brasileiro Série B 2026",
    "categorias_12m": { "Série B": 28, "Sub-20": 3 },
    "consultadoEm": "2026-10-02 06:12:40",
    "erro": null
  },
  "elenco": { "pertence": true, "grupo": "profissional", "categoria": "profissional" }
}

situacaoBid é null quando a consulta diária ainda não passou por esse atleta.

elenco.pertence é false para quem já teve registro no clube mas não tem vínculo ativo hoje.

GET/api/v1/elencochave obrigatória

O mesmo cálculo da página /elenco: a partir do registro mais recente de cada pessoa, quem segue com vínculo ativo hoje. Vem agrupado em comissão técnica, profissional, sub-20 com contrato profissional, base por ano de nascimento, registrados em outro clube e feminino.

Parâmetros

Este endpoint não aceita parâmetros.

Exemplo de requisição

curl -s -H "Authorization: Bearer $BID_API_KEY" \
  "https://bid.avaifc.com/api/v1/elenco"

Exemplo de resposta

{
  "hoje": "2026-10-02",
  "dadosAte": "2026-10-01 18:30:00",
  "totais": {
    "atletas": 71,
    "comissaoTecnica": 6,
    "profissional": 28,
    "sub20Profissional": 7,
    "base": 36,
    "feminino": 0,
    "outroClube": 4
  },
  "consultaBid": { "ate": "2026-10-02 06:12:40", "consultados": 75, "semConsulta": 2 },
  "comissaoTecnica": [
    {
      "codigo_atleta": "501188",
      "nome": "JORGE LUIZ ALVES",
      "apelido": "Jorge Alves",
      "tipo_contrato": "Contrato Treinador/Assistente Técnico",
      "vinculo": "comissao",
      "data_publicacao": "2026-06-11 17:05:00",
      "data_inicio": "2026-06-10",
      "data_termino": null,
      "idade": 48,
      "aviso": null
    }
  ],
  "grupos": [
    {
      "id": "profissional",
      "titulo": "Profissional",
      "descricao": "Contrato profissional ativo, 21 anos ou mais na temporada…",
      "total": 28,
      "categorias": [
        {
          "id": "profissional",
          "titulo": "Profissional",
          "descricao": "Contrato profissional ativo.",
          "total": 28,
          "pessoas": [
            {
              "codigo_atleta": "742193",
              "apelido": "Joao Pedro",
              "tipo_contrato": "Contrato Definitivo",
              "vinculo": "profissional",
              "data_termino": "2026-12-31",
              "meses_restantes": 2,
              "dias_restantes": 90,
              "jogos12m": { "profissional": 28, "base": 3, "outra": 0, "total": 31 },
              "registradoEmOutroClube": false
            }
          ]
        }
      ]
    }
  ],
  "clubes": ["20058"],
  "geradoEm": "2026-10-02T12:00:00.000Z"
}

Resposta resumida acima: cada pessoa traz ainda apelido, sexo, idade_temporada, contrato_reativado, categorias12m, ultimo_jogo e consultadoEm.

O grupo outro-clube só aparece quando existem consultas por atleta no banco.

GET/api/v1/estatisticaschave obrigatória

Números agregados do acervo: quantos registros e atletas, quanto veio do monitor e quanto da mineração do histórico, registros por ano, as últimas execuções do monitor e o progresso da mineração dia a dia desde 2003.

Parâmetros

Este endpoint não aceita parâmetros.

Exemplo de requisição

curl -s -H "Authorization: Bearer $BID_API_KEY" \
  "https://bid.avaifc.com/api/v1/estatisticas"

Exemplo de resposta

{
  "registros": 4182,
  "jogadoresUnicos": 1337,
  "porOrigem": { "monitor": 318, "historico": 3864 },
  "primeiraPublicacao": "2003-01-14 00:00:00",
  "ultimaPublicacao": "2026-10-01 18:30:00",
  "porAno": [
    { "year": "2003", "count": 112 },
    { "year": "2004", "count": 98 }
  ],
  "monitor": {
    "ultimo": {
      "id": 8421,
      "started_at": "2026-10-02T11:40:02.118Z",
      "finished_at": "2026-10-02T11:40:49.774Z",
      "status": "ok",
      "dates_checked": ["2026-10-02"],
      "records_found": 0,
      "new_records": 0,
      "notified": 0,
      "captcha_attempts": 1,
      "error": null,
      "duration_ms": 47656
    },
    "ultimoSucesso": "2026-10-02T11:40:49.774Z",
    "runs": []
  },
  "backfill": {
    "iniciado": true,
    "inicio": "2003-01-01",
    "fim": "2026-10-01",
    "diasOk": 8676,
    "diasErro": 2,
    "diasDesistidos": 0,
    "diasTotal": 8676,
    "percentual": 100,
    "ultimoDia": "2026-10-01",
    "diasRestantes": 0,
    "ritmoDiasPorHora": 240,
    "ritmoFonte": "estimado",
    "previsaoTermino": null,
    "concluido": true,
    "atualizadoEm": "2026-10-02T09:14:00.000Z",
    "parado": false
  },
  "clubes": ["20058"],
  "geradoEm": "2026-10-02T12:00:00.000Z"
}

monitor.runs traz as 20 execuções mais recentes; foi omitido no exemplo.

GET/api/v1/saudesem chave

Único endpoint que não pede chave, para monitoramento externo. Responde 200 quando o banco responde e 503 quando não. Também diz até quando o acervo tem dados e quando o monitor rodou com sucesso pela última vez.

Parâmetros

Este endpoint não aceita parâmetros.

Exemplo de requisição

curl -s "https://bid.avaifc.com/api/v1/saude"

Exemplo de resposta

{
  "status": "ok",
  "dadosAte": "2026-10-01 18:30:00",
  "ultimaExecucaoMonitor": "2026-10-02T11:40:49.774Z",
  "geradoEm": "2026-10-02T12:00:00.000Z"
}

GET/api/v1/openapi.jsonsem chave

O contrato da API em OpenAPI 3.1, gerado do mesmo objeto que gera esta página. Serve para importar em Postman/Insomnia, gerar clientes ou alimentar uma ferramenta de IA.

Parâmetros

Este endpoint não aceita parâmetros.

Exemplo de requisição

curl -s "https://bid.avaifc.com/api/v1/openapi.json"

Exemplo de resposta

{
  "openapi": "3.1.0",
  "info": { "title": "API do BID do Avaí", "version": "1.0.0" },
  "servers": [{ "url": "https://bid.avaifc.com" }],
  "paths": { "/api/v1/registros": { "get": { "operationId": "registros" } } }
}

Exemplos resolvidos

Três tarefas comuns, do início ao fim.

Últimas contratações

As dez contratações mais recentes, com nome e vigência do contrato.

  • Filtre por categoria=contratacao para juntar as várias redações do BID ('Contrato Definitivo', 'Transferencia Definitiva'…).
  • Mantenha ordem=recentes (o padrão) e limit=10.
  • Leia apelido, data_publicacao, data_inicio e data_termino de cada item.

Python

import os, requests

chave = os.environ["BID_API_KEY"]
r = requests.get(
    "https://bid.avaifc.com/api/v1/registros",
    params={"categoria": "contratacao", "limit": 10},
    headers={"Authorization": f"Bearer {chave}"},
    timeout=30,
)
r.raise_for_status()

for reg in r.json()["registros"]:
    nome = reg["apelido"] or reg["nome"]
    print(reg["data_publicacao"][:10], nome, reg["tipo_contrato"],
          f'{reg["data_inicio"]} → {reg["data_termino"]}')

Elenco atual

Listar o elenco profissional de hoje e quem está emprestado para fora.

  • Chame /elenco: ele já vem agrupado e calculado para o dia de hoje em Brasília.
  • Percorra grupos e, dentro de cada um, categorias e pessoas.
  • O grupo outro-clube são os emprestados para fora — eles não entram nas contagens do elenco.

Python

import os, requests

chave = os.environ["BID_API_KEY"]
r = requests.get("https://bid.avaifc.com/api/v1/elenco",
                 headers={"Authorization": f"Bearer {chave}"}, timeout=30)
r.raise_for_status()
elenco = r.json()

print("Elenco em", elenco["hoje"], "| dados até", elenco["dadosAte"])
for grupo in elenco["grupos"]:
    print(f'\n== {grupo["titulo"]} ({grupo["total"]})')
    for cat in grupo["categorias"]:
        for p in cat["pessoas"]:
            print(" -", p["apelido"] or p["nome"], "|", p["tipo_contrato"],
                  "| até", p["data_termino"])

Ficha de um atleta

Achar um atleta pelo nome e ler a história dele no clube.

  • Procure em /atletas?busca=<nome> e pegue o codigo_atleta do resultado.
  • Chame /atletas/{codigo} para o resumo, todos os registros e a situação atual no BID.
  • Se situacaoBid.clube_codigo não for 20058, ele está registrado em outro clube hoje.

Python

import os, requests

chave = os.environ["BID_API_KEY"]
sessao = requests.Session()
sessao.headers["Authorization"] = f"Bearer {chave}"

busca = sessao.get("https://bid.avaifc.com/api/v1/atletas",
                   params={"busca": "joao", "limit": 1}, timeout=30)
busca.raise_for_status()
atletas = busca.json()["atletas"]
if not atletas:
    raise SystemExit("ninguém encontrado")

codigo = atletas[0]["codigo_atleta"]
ficha = sessao.get(f"https://bid.avaifc.com/api/v1/atletas/{codigo}", timeout=30)
ficha.raise_for_status()
d = ficha.json()

print(d["atleta"]["apelido"], "-", d["atleta"]["totalRegistros"], "registros")
print("No elenco agora?", d["elenco"]["pertence"], d["elenco"]["grupo"])
if d["situacaoBid"] and d["situacaoBid"]["clube_codigo"] != "20058":
    print("Registrado hoje em:", d["situacaoBid"]["clube_nome"])
for reg in d["registros"][:5]:
    print(" ", reg["data_publicacao"][:10], reg["tipo_contrato"])

Dicionário de dados

O que cada campo significa no BID.

Registro do BID

Um item de /registros e de registros[] na ficha do atleta. É a linha que a CBF publicou no BID.

CampoTipoSignificado
record_keystringIdentificador estável do registro, calculado por nós (atleta + contrato + tipo + publicação). Use-o para deduplicar: o BID republica a mesma linha quando o status muda.
codigo_atletastringCódigo CBF da pessoa. É a chave para /atletas/{codigo}.
nomestring | nullNome civil completo, como o BID escreve (em geral em maiúsculas).
apelidostring | nullNome esportivo, o que aparece na camisa.
tipo_contratostring | nullStatus ATUAL do registro no BID, não o evento que o criou. 'Contrato Definitivo', 'Contrato Emprestimo', 'Rescisão', 'Vinculo Encerrado', 'Reversão', 'Vínculo Não Profissional'… A redação varia muito ao longo dos anos.
id_contratostring | nullIdentificador do contrato no BID.
contrato_numerostring | nullNúmero do contrato no clube. Uma rescisão reaproveita o número do contrato que ela encerra.
data_publicacaostring | nullQuando a CBF publicou no BID, no horário de Brasília, no formato 'AAAA-MM-DD HH:MM:SS' (sem fuso: não passe por new Date() esperando UTC). É o campo de ordenação e dos filtros desde/ate.
data_iniciostring | nullInício da vigência do vínculo ('AAAA-MM-DD').
data_terminostring | nullFim da vigência ('AAAA-MM-DD'). Em contratos de comissão técnica sem prazo o BID repete a data de início.
data_nascimentostring | nullNascimento ('AAAA-MM-DD'), quando o BID informa.
sexostring | nullComo o BID manda: '1' masculino, '0' feminino.
codigo_clubestring | nullCódigo do clube no BID. Aqui é sempre 20058 (Avaí Futebol Clube).
clubestring | nullNome do clube como o BID escreve.
ufstring | nullFederação do clube ('SC').
origem'monitor' | 'historico''monitor' = capturado ao vivo quando saiu; 'historico' = recuperado pela mineração dia a dia do passado. Só muda como o dado chegou até nós, não a confiabilidade.
first_seen_atstring | nullQuando gravamos o registro pela primeira vez (instante ISO, UTC).
notified_atstring | nullQuando o registro foi anunciado no canal do Telegram; null para o que veio do histórico.

Atleta

Um item de /atletas e o campo atleta da ficha: a pessoa, resumida a partir dos registros dela.

CampoTipoSignificado
codigo_atletastringCódigo CBF.
nome / apelidostring | nullComo no registro mais recente dele.
data_nascimentostring | null'AAAA-MM-DD', do registro mais recente.
idadeinteiro | nullAnos completos hoje (Brasília); null sem data de nascimento.
sexostring | null'1' masculino, '0' feminino.
totalRegistrosinteiroQuantos registros ele tem no clube — inclui as rescisões.
primeiroRegistrostring | nulldata_publicacao do registro mais antigo dele.
ultimoRegistrostring | nulldata_publicacao do registro mais recente dele.
ultimoTipostring | nulltipo_contrato desse registro mais recente: é o que diz se ele ainda está no clube.
situacaoAtualobjeto | nullDa consulta diária do BID por atleta: clube_codigo, clube_nome, tipo_contrato e desde (data_inicio). Pode apontar outro clube. null quando essa consulta ainda não passou por ele.
urlstringLink absoluto para a página dele no site.

Situação no BID (situacaoBid)

A última consulta por atleta feita direto no BID, atualizada diariamente. É o que revela empréstimo para fora.

CampoTipoSignificado
clube_codigo / clube_nomestring | nullClube do registro ATIVO hoje segundo o BID.
tipo_contratostring | nullStatus desse registro atual.
contrato_numerostring | nullNúmero do contrato atual.
data_iniciostring | nullInício do registro atual ('AAAA-MM-DD').
data_publicacaostring | nullPublicação do registro atual (Brasília, sem fuso).
jogos_totalinteiro | nullJogos que o BID lista na carreira dele.
jogos_pelo_clube_12minteiro | nullJogos pelo clube nos últimos 12 meses.
ultimo_jogo_data / _categoria / _campeonatostring | nullÚltimo jogo que o BID registra, com a categoria ('Série B', 'Sub-20'…) e o campeonato.
categorias_12mobjeto | null{categoria: jogos} nos últimos 12 meses. É daqui que sai a estimativa de base × profissional.
consultadoEmstring | nullQuando essa consulta rodou (Brasília, sem fuso).
errostring | nullPreenchido quando a última tentativa falhou — os dados acima são de uma consulta anterior.

Elenco

A resposta de /elenco, igual à da página /elenco do site.

CampoTipoSignificado
hojestringDia (Brasília) para o qual o elenco foi calculado.
dadosAtestring | nullPublicação mais recente que temos para o clube.
totaisobjetoatletas, comissaoTecnica, profissional, sub20Profissional, base, feminino e outroClube (estes últimos não entram na contagem do elenco).
consultaBidobjeto | nullate (consulta mais recente), consultados e semConsulta. null quando não há consultas por atleta.
comissaoTecnicalistaContratos de treinador/assistente técnico ativos.
gruposlistaprofissional, sub20-profissional, base, outro-clube e feminino. Cada grupo tem categorias, e cada categoria tem pessoas.
pessoa.vinculo'profissional' | 'base' | 'comissao'Tipo de vínculo que o registro mais recente dela indica.
pessoa.jogos12mobjeto | nullprofissional, base, outra e total — jogos nos últimos 12 meses por tipo de competição.
pessoa.registradoEmOutroClubebooleanoA consulta por atleta mostra registro ativo em outro clube (emprestado para fora).
pessoa.avisostring | nullRessalva sobre o dado (por exemplo contrato sem prazo e antigo).

Como interpretar (leia antes de publicar número)

O BID é preciso, mas diz menos do que parece.

tipo_contrato é o status atual, não o evento

O BID republica a linha de um registro quando ele muda, e o tipo descreve como ele está AGORA. Uma linha com 'Vinculo Encerrado' não quer dizer que o encerramento aconteceu naquele dia: quer dizer que, na publicação daquele dia, aquele vínculo estava encerrado. Para saber quem está no clube hoje, olhe o registro mais recente da pessoa (ultimoTipo) ou use /elenco.

Quem o Avaí empresta para fora não aparece com o Avaí

Um atleta emprestado é registrado pelo clube que o recebe, então ele não sai em /registros do Avaí enquanto estiver lá. A única forma de vê-lo é a consulta diária por atleta: situacaoAtual / situacaoBid aponta o outro clube, e no /elenco ele vai para o grupo outro-clube.

Base × profissional é estimativa nossa

O BID não diz em que categoria a pessoa joga. A separação do /elenco combina o tipo de vínculo, a idade por ano de nascimento (como nas categorias da CBF) e os jogos dos últimos 12 meses por categoria. Um sub-20 com contrato profissional e jogos em competição profissional é contado como profissional. É um palpite bem informado, não um dado oficial.

O BID não informa a função da comissão técnica

Todos os contratos de comissão vêm como 'Contrato Treinador/Assistente Técnico'. Não há como saber pelo BID quem é técnico principal, auxiliar, preparador ou da base. Contratos sem prazo só saem da lista quando o clube publica a rescisão, então registros antigos podem estar desatualizados.

Datas vêm no horário de Brasília, sem fuso

data_publicacao e companhia são strings 'AAAA-MM-DD HH:MM:SS' no horário de Brasília. Passar isso por new Date() faz o JavaScript ler como UTC e deslocar o dia. Trate como texto ou acrescente o fuso explicitamente. Só first_seen_at, notified_at e geradoEm são instantes ISO em UTC.

O histórico ainda pode estar sendo minerado

Os registros antigos são recuperados dia a dia desde 2003. Enquanto isso não termina, /estatisticas mostra o progresso em backfill, e registros novos podem aparecer no meio da lista — por isso a paginação por cursor é mais segura que por offset.

Versionamento e changelog

  • O caminho começa com /api/v1. Enquanto for v1, não removemos nem renomeamos campos e não mudamos o significado de nenhum deles.
  • Campos novos podem ser acrescentados a qualquer momento: ignore o que você não conhece em vez de validar a resposta de forma estrita.
  • Mudança que quebre compatibilidade só em /api/v2, com o v1 funcionando em paralelo por um tempo.

Changelog

v1 — 2026-10-02

  • Primeira versão pública: registros, atletas, ficha do atleta, elenco, estatísticas, saúde e OpenAPI.
  • Autenticação por chave de API, limite de 600 requisições por minuto por chave.