Mata-mata sem dor: o endpoint de chaveamento

Publicado em , atualizado em .

Copa do Brasil e Libertadores não cabem numa tabela — são árvore, não lista. Veja como montar o bracket completo, com ida, volta e pênaltis, numa única chamada.

A competição em que ninguém tem semana seguinte

O pontos corridos perdoa. Você toma 4 a 0 numa quarta-feira e no domingo recomeça do zero, com 3 pontos disponíveis como todo mundo. Trinta e oito rodadas dão tempo de errar.

O mata-mata não perdoa nada. É uma competição em que cada jogo pode ser o último, e é justamente isso que produz as histórias que o futebol brasileiro conta por décadas: o clube de Série D que elimina um grande na Copa do Brasil, a virada por três gols de diferença nas quartas de Libertadores, a decisão que vai para os pênaltis depois de 180 minutos empatados.

A Copa do Brasil é o exemplo mais radical disso — uma competição nacional que reúne clubes de todas as federações estaduais, onde um time de cidade pequena entra no mesmo chaveamento que o campeão brasileiro e, por 90 minutos, tem exatamente a mesma chance que ele.

Por que isso quebra o seu modelo de dados

O problema de quem constrói é que essas duas competições não têm a mesma forma.

Pontos corridos é uma lista: vinte times, uma ordem, uma tabela. Você lê de cima para baixo e acabou.

Mata-mata é uma árvore: fases que se afunilam, confrontos que podem ter um ou dois jogos, agregado de ida e volta, critério de desempate, disputa de pênaltis, e vencedores que só existem depois que a fase anterior terminou. Modelar isso como “lista de partidas” funciona até a primeira vez que alguém pede para desenhar o chaveamento na tela.

Pior: metade da árvore ainda não existe. Nas oitavas, ninguém sabe quem joga as quartas. O dado é incompleto por natureza, não por falha.

O bracket na API

O endpoint de chaveamento entrega essa árvore inteira de uma vez:

curl https://api.dadosfutebol.com.br/v1/campeonatos/62/chave \
  -H "Authorization: Bearer SUA_CHAVE_AQUI"

A resposta é organizada por fase, e cada fase carrega seus confrontos (as “chaves”):

{
  "data": {
    "campeonato": { "id": 62, "nome": "Copa do Brasil" },
    "fases": [
      {
        "nome": "Primeira fase",
        "ordem": 1,
        "eliminatorio": true,
        "ida_e_volta": false,
        "status": "encerrada",
        "chaves": [
          {
            "id": 111,
            "nome": "Chave 2",
            "partida_ida": {
              "id": 3783,
              "time_mandante": { "id": 250, "nome": "Ivinhema", "sigla": "IVI" },
              "time_visitante": { "id": 100, "nome": "Independente-AP", "sigla": "IND" },
              "placar_mandante": 1,
              "placar_visitante": 0,
              "disputa_penalti": false,
              "status": "encerrado",
              "estadio": "Saraivão"
            },
            "partida_volta": null
          }
        ]
      }
    ]
  }
}

Repare nos nomes do exemplo: Ivinhema e Independente-AP, do Mato Grosso do Sul e do Amapá. É a Copa do Brasil sendo a Copa do Brasil.

Como ler a estrutura

  • ida_e_volta diz se o confronto tem dois jogos. Em fase de jogo único, partida_volta vem null — como na primeira fase da Copa do Brasil acima.
  • disputa_penalti e o campo penalti aparecem quando a decisão foi para as penalidades, com o placar da disputa.
  • ordem define a progressão das fases (na Copa do Brasil 2026: cinco fases iniciais e oitavas de final até aqui — as fases seguintes entram na resposta conforme os confrontos são sorteados).

Um detalhe de design honesto: confronto não sorteado é ausência de dado, não placeholder. A API não inventa “Time A x Time B” — a chave aparece quando existe de verdade na fonte. É a metade da árvore que ainda não existe, representada como ela é.

Fases também têm tabela

Mata-matas com fase de grupos (como a Libertadores) expõem a classificação por grupo em GET /v1/campeonatos/{id}/fases/{faseId}/tabela — mesma estrutura da tabela de pontos corridos, uma por grupo. É o formato híbrido: começa lista, termina árvore.