# API do BID do Avaí — referência completa > API pública de leitura dos registros do Avaí Futebol Clube (clube 20058 no BID da CBF) de 2003-01-01 até hoje: contratações, rescisões, empréstimos, renovações, elenco atual e estatísticas. Respostas em JSON, autenticação por chave de API. Este arquivo é autossuficiente: com ele dá para escrever um cliente funcional sem consultar mais nada. ## De onde vem o dado Tudo aqui sai do BID (Boletim Informativo Diário) da CBF, e de nenhuma outra fonte. São os registros do Avaí Futebol Clube (código 20058 no BID), de 2003-01-01 até hoje, coletados de duas formas: - um monitor consulta o BID a cada 20 minutos e grava as publicações novas (origem "monitor"); - uma mineração percorre o passado dia a dia desde 2003-01-01 (origem "historico"). Uma terceira rotina consulta o BID atleta por atleta, uma vez por dia, e guarda onde cada pessoa está registrada no momento. É a única forma de saber que alguém foi emprestado para outro clube. ## URL base e autenticação URL base: https://bid.avaifc.com/api/v1 Toda chamada é um GET e devolve JSON. Mande a chave em um destes dois cabeçalhos: ``` Authorization: Bearer SUA_CHAVE X-API-Key: SUA_CHAVE ``` Sem chave válida a resposta é 401. Os endpoints /api/v1/saude e /api/v1/openapi.json não pedem chave. Peça uma chave pelo contato na página de documentação. Nunca coloque a chave em código que roda no navegador do usuário: chame a API a partir do seu servidor. ## Limites e cache - 600 requisições por 1 minuto por chave; 120 por minuto por IP quando não há chave válida. - Cabeçalhos de cada resposta: X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset (epoch em segundos). - Ao estourar o limite: 429 com o corpo de erro padrão e o cabeçalho Retry-After. - Sucesso vem com `Cache-Control: public, max-age=60, stale-while-revalidate=120`. Pode cachear por 60s. - CORS liberado para qualquer origem (Access-Control-Allow-Origin: *). ## Formato de erro Todo erro da API tem o mesmo corpo: ```json { "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" } } } ``` Códigos possíveis: - `api_nao_configurada` (HTTP 503): O servidor está sem nenhuma chave configurada. Nada a fazer do lado de quem chama. - `nao_autenticado` (HTTP 401): Chave ausente, com erro de digitação ou revogada. - `parametro_invalido` (HTTP 400): Algum parâmetro saiu do formato ou da faixa aceita. detalhes diz qual e o que era esperado. - `nao_encontrado` (HTTP 404): Código de atleta desconhecido ou fora do formato. - `limite_excedido` (HTTP 429): Você passou do limite de requisições por minuto. - `erro_interno` (HTTP 500): Falha nossa ao consultar o banco. Tente de novo em instantes. ## Paginação por cursor /api/v1/registros pagina por cursor. Chame sem cursor, leia `paginacao.proximoCursor` e repita passando esse valor em `?cursor=` até receber `null`. O cursor é opaco: não tente interpretá-lo. Por que cursor e não offset: o histórico ainda pode estar sendo minerado, então registros antigos aparecem no meio da lista e deslocariam as páginas seguintes. Com cursor isso não acontece. `offset` existe para casos simples e é ignorado quando há cursor. ```python 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") ``` ## Endpoints ### GET /api/v1/registros 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. Autenticação: obrigatória. Parâmetros: - `ordem` — enum (valores: recentes | antigos; padrão: recentes): Ordenação por data de publicação. - `limit` — inteiro (faixa: 1..100; padrão: 25; exemplo: 50): Quantos itens trazer por página. - `cursor` — string (exemplo: eyJkIjoiMjAyNC0wMS0zMSAxNDoyMDowMCIsImsiOiJhYmMifQ): 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. - `offset` — inteiro (faixa: 0..10000000; padrão: 0): Paginação simples por deslocamento. Ignorado quando cursor é enviado. - `desde` — data (exemplo: 2024-01-01): Só registros publicados nesse dia ou depois (data_publicacao). - `ate` — data (exemplo: 2024-12-31): Só registros publicados até esse dia, incluindo o dia inteiro. - `atleta` — string (exemplo: 123456): Código CBF do atleta (codigo_atleta). - `tipo` — string (exemplo: Contrato Definitivo): tipo_contrato exato, sem diferenciar maiúsculas nem acentos. Use quando você quer um status específico do BID, e não um agrupamento. - `categoria` — enum (valores: contratacao | rescisao | emprestimo | renovacao | base | liberacao | transferencia | outros; exemplo: contratacao): 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. Exemplo de requisição: ```bash curl -s -H "Authorization: Bearer $BID_API_KEY" \ "https://bid.avaifc.com/api/v1/registros?limit=2&categoria=contratacao" ``` Exemplo de resposta: ```json { "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" } } ``` Nota: total é o número de registros que casam com os filtros, não o tamanho da página. Nota: Para varrer tudo, repita a chamada com cursor = paginacao.proximoCursor até receber null. ### GET /api/v1/atletas 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. Autenticação: obrigatória. Parâmetros: - `busca` — string (exemplo: joao): Procura por nome, apelido ou código, sem diferenciar maiúsculas nem acentos. O atleta entra na lista quando qualquer registro dele casa. - `page` — inteiro (faixa: 1..100000; padrão: 1): Página (1 é a primeira). - `limit` — inteiro (faixa: 1..100; padrão: 25; exemplo: 50): Quantos itens trazer por página. Exemplo de requisição: ```bash curl -s -H "Authorization: Bearer $BID_API_KEY" \ "https://bid.avaifc.com/api/v1/atletas?busca=joao&limit=1" ``` Exemplo de resposta: ```json { "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" } } ``` Nota: situacaoAtual vem da consulta diária por atleta e pode apontar outro clube (empréstimo para fora). Nota: idade é calculada no fuso de Brasília; é null quando o BID não traz data de nascimento. ### GET /api/v1/atletas/{codigo} 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. Autenticação: obrigatória. Parâmetros: - `codigo` — string (caminho) (exemplo: 742193): Código CBF do atleta. Código desconhecido ou fora do formato responde 404. Exemplo de requisição: ```bash curl -s -H "Authorization: Bearer $BID_API_KEY" \ "https://bid.avaifc.com/api/v1/atletas/742193" ``` Exemplo de resposta: ```json { "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" } } ``` Nota: situacaoBid é null quando a consulta diária ainda não passou por esse atleta. Nota: elenco.pertence é false para quem já teve registro no clube mas não tem vínculo ativo hoje. ### GET /api/v1/elenco 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. Autenticação: obrigatória. Parâmetros: nenhum. Exemplo de requisição: ```bash curl -s -H "Authorization: Bearer $BID_API_KEY" \ "https://bid.avaifc.com/api/v1/elenco" ``` Exemplo de resposta: ```json { "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" } ``` Nota: Resposta resumida acima: cada pessoa traz ainda apelido, sexo, idade_temporada, contrato_reativado, categorias12m, ultimo_jogo e consultadoEm. Nota: O grupo outro-clube só aparece quando existem consultas por atleta no banco. ### GET /api/v1/estatisticas 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. Autenticação: obrigatória. Parâmetros: nenhum. Exemplo de requisição: ```bash curl -s -H "Authorization: Bearer $BID_API_KEY" \ "https://bid.avaifc.com/api/v1/estatisticas" ``` Exemplo de resposta: ```json { "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" } ``` Nota: monitor.runs traz as 20 execuções mais recentes; foi omitido no exemplo. ### GET /api/v1/saude Ú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. Autenticação: não é necessária. Parâmetros: nenhum. Exemplo de requisição: ```bash curl -s "https://bid.avaifc.com/api/v1/saude" ``` Exemplo de resposta: ```json { "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.json 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. Autenticação: não é necessária. Parâmetros: nenhum. Exemplo de requisição: ```bash curl -s "https://bid.avaifc.com/api/v1/openapi.json" ``` Exemplo de resposta: ```json { "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" } } } } ``` ## Dicionário de dados ### Registro do BID Um item de /registros e de registros[] na ficha do atleta. É a linha que a CBF publicou no BID. - `record_key` — string: Identificador 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_atleta` — string: Código CBF da pessoa. É a chave para /atletas/{codigo}. - `nome` — string | null: Nome civil completo, como o BID escreve (em geral em maiúsculas). - `apelido` — string | null: Nome esportivo, o que aparece na camisa. - `tipo_contrato` — string | null: Status 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_contrato` — string | null: Identificador do contrato no BID. - `contrato_numero` — string | null: Número do contrato no clube. Uma rescisão reaproveita o número do contrato que ela encerra. - `data_publicacao` — string | null: Quando 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_inicio` — string | null: Início da vigência do vínculo ('AAAA-MM-DD'). - `data_termino` — string | null: Fim da vigência ('AAAA-MM-DD'). Em contratos de comissão técnica sem prazo o BID repete a data de início. - `data_nascimento` — string | null: Nascimento ('AAAA-MM-DD'), quando o BID informa. - `sexo` — string | null: Como o BID manda: '1' masculino, '0' feminino. - `codigo_clube` — string | null: Código do clube no BID. Aqui é sempre 20058 (Avaí Futebol Clube). - `clube` — string | null: Nome do clube como o BID escreve. - `uf` — string | null: Federaçã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_at` — string | null: Quando gravamos o registro pela primeira vez (instante ISO, UTC). - `notified_at` — string | null: Quando 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. - `codigo_atleta` — string: Código CBF. - `nome / apelido` — string | null: Como no registro mais recente dele. - `data_nascimento` — string | null: 'AAAA-MM-DD', do registro mais recente. - `idade` — inteiro | null: Anos completos hoje (Brasília); null sem data de nascimento. - `sexo` — string | null: '1' masculino, '0' feminino. - `totalRegistros` — inteiro: Quantos registros ele tem no clube — inclui as rescisões. - `primeiroRegistro` — string | null: data_publicacao do registro mais antigo dele. - `ultimoRegistro` — string | null: data_publicacao do registro mais recente dele. - `ultimoTipo` — string | null: tipo_contrato desse registro mais recente: é o que diz se ele ainda está no clube. - `situacaoAtual` — objeto | null: Da 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. - `url` — string: Link 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. - `clube_codigo / clube_nome` — string | null: Clube do registro ATIVO hoje segundo o BID. - `tipo_contrato` — string | null: Status desse registro atual. - `contrato_numero` — string | null: Número do contrato atual. - `data_inicio` — string | null: Início do registro atual ('AAAA-MM-DD'). - `data_publicacao` — string | null: Publicação do registro atual (Brasília, sem fuso). - `jogos_total` — inteiro | null: Jogos que o BID lista na carreira dele. - `jogos_pelo_clube_12m` — inteiro | null: Jogos pelo clube nos últimos 12 meses. - `ultimo_jogo_data / _categoria / _campeonato` — string | null: Último jogo que o BID registra, com a categoria ('Série B', 'Sub-20'…) e o campeonato. - `categorias_12m` — objeto | null: {categoria: jogos} nos últimos 12 meses. É daqui que sai a estimativa de base × profissional. - `consultadoEm` — string | null: Quando essa consulta rodou (Brasília, sem fuso). - `erro` — string | null: Preenchido 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. - `hoje` — string: Dia (Brasília) para o qual o elenco foi calculado. - `dadosAte` — string | null: Publicação mais recente que temos para o clube. - `totais` — objeto: atletas, comissaoTecnica, profissional, sub20Profissional, base, feminino e outroClube (estes últimos não entram na contagem do elenco). - `consultaBid` — objeto | null: ate (consulta mais recente), consultados e semConsulta. null quando não há consultas por atleta. - `comissaoTecnica` — lista: Contratos de treinador/assistente técnico ativos. - `grupos` — lista: profissional, 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.jogos12m` — objeto | null: profissional, base, outra e total — jogos nos últimos 12 meses por tipo de competição. - `pessoa.registradoEmOutroClube` — booleano: A consulta por atleta mostra registro ativo em outro clube (emprestado para fora). - `pessoa.aviso` — string | null: Ressalva sobre o dado (por exemplo contrato sem prazo e antigo). ## Avisos de interpretação ### 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. ## Exemplos resolvidos ### Ú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= 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"]) ``` ## Versionamento - 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. ## Links - Documentação: https://bid.avaifc.com/docs - OpenAPI v1: https://bid.avaifc.com/api/v1/openapi.json - Índice curto: https://bid.avaifc.com/llms.txt - Site: https://bid.avaifc.com/ - Elenco atual: https://bid.avaifc.com/elenco