campeonato-brasileiro-api
Version:
API moderna para consultar classificação e rodada atual das Séries A, B, C e D do Brasileirão
577 lines (465 loc) • 12.1 kB
Markdown
# campeonato-brasileiro-api
[](https://www.npmjs.com/package/campeonato-brasileiro-api)
[](https://www.npmjs.com/package/campeonato-brasileiro-api)
API moderna para consultar classificação e rodada atual das Séries A, B, C e D do Brasileirão.
## Compatibilidade
- Node.js `18+`
- Sem dependências de runtime
- Compatível com `require()` e `import`
## Instalação
```bash
npm install campeonato-brasileiro-api
```
## Métodos disponíveis
| Método | Descrição |
| --- | --- |
| `listSeries()` | Lista as séries suportadas |
| `getCompetition(serie, options?)` | Retorna o payload completo normalizado |
| `getStandings(serie, options?)` | Retorna apenas classificação e legendas |
| `getTable(serie, options?)` | Retorna uma tabela única |
| `getGroups(serie, options?)` | Retorna os grupos da Série D |
| `getRounds(serie, options?)` | Retorna a rodada atual normalizada |
| `getCurrentRound(serie, options?)` | Alias de `getRounds()` |
| `tabela(serie, options?)` | Helper legado de classificação |
| `rodadaAtual(serie, rodada?, options?)` | Helper legado de jogos da rodada |
## Uso rápido
### CommonJS
```js
const brasileirao = require('campeonato-brasileiro-api');
const data = await brasileirao.getCompetition('a');
console.log(data.competition.name);
console.log(data.tables[0].entries[0].team.name);
console.log(data.rounds[0].matches.length);
```
### ESM
```js
import { getStandings, getRounds } from 'campeonato-brasileiro-api';
const standings = await getStandings('b');
const rounds = await getRounds('b');
console.log(standings.tables[0].entries[0]);
console.log(rounds.rounds[0].matches);
```
## Exemplos completos
### `listSeries()`
```js
const brasileirao = require('campeonato-brasileiro-api');
const series = brasileirao.listSeries();
console.log(series);
```
Saída esperada:
```js
[
{
code: 'a',
slug: 'brasileirao-serie-a',
name: 'Campeonato Brasileiro Série A',
grouped: false,
url: 'https://...'
},
{
code: 'd',
slug: 'brasileirao-serie-d',
name: 'Campeonato Brasileiro Série D',
grouped: true,
url: 'https://...'
}
]
```
### `getCompetition(serie, options?)`
Retorna o contrato principal do pacote:
- metadados da competição
- legendas
- tabelas
- rodadas
- jogos da rodada atual
```js
const brasileirao = require('campeonato-brasileiro-api');
const competition = await brasileirao.getCompetition('a');
console.log(competition);
```
Exemplo de shape:
```js
{
competition: {
code: 'a',
slug: 'brasileirao-serie-a',
name: 'Campeonato Brasileiro Série A 2026',
season: 2026,
sport: 'futebol',
grouped: false,
phase: {
slug: 'fase-unica-campeonato-brasileiro-2026',
disclaimer: '',
description: 'Pontos Corridos',
typeId: '1',
grouped: false
},
edition: {
name: 'Campeonato Brasileiro Série A 2026',
location: 'Brasil',
startsAt: '2026-03-28',
endsAt: '2026-12-06',
regulation: '...'
},
source: {
provider: 'source',
url: 'https://...',
resourceId: '...',
tUUID: '...'
}
},
grouped: false,
legends: [
{ id: 1, name: 'Libertadores', color: '#0000ff' }
],
tables: [
{
id: 'overall',
name: 'Classificacao geral',
round: { number: 13, total: 38, label: '13a rodada' },
entries: [
{
position: 1,
team: {
id: 275,
name: 'Palmeiras',
shortName: 'PAL',
badge: 'https://...'
},
points: 32,
matches: 13,
wins: 10,
draws: 2,
losses: 1,
goalsFor: 23,
goalsAgainst: 10,
goalDifference: 13,
efficiency: 82,
movement: 0,
recentForm: ['W', 'W', 'D', 'W', 'W'],
legend: { id: 1, name: 'Libertadores', color: '#0000ff' }
}
]
}
],
rounds: [
{
id: 'overall',
groupId: null,
groupName: null,
number: 13,
total: 38,
label: '13a rodada',
matches: [
{
id: 346376,
round: 13,
totalRounds: 38,
dateTime: '2026-04-25T18:30',
date: '2026-04-25',
time: '18:30',
started: true,
status: 'finished',
statusCode: 'ENCERRADA',
venue: 'Mané Garrincha',
homeTeam: { id: 263, name: 'Botafogo', shortName: 'BOT', badge: 'https://...' },
awayTeam: { id: 285, name: 'Internacional', shortName: 'INT', badge: 'https://...' },
score: { home: 2, away: 2, penalties: null },
coverage: {
label: 'saiba como foi',
url: 'https://...',
statusCode: 'ENCERRADA'
}
}
]
}
],
matches: [
{
id: 346376,
round: 13,
status: 'finished'
}
]
}
```
### `getStandings(serie, options?)`
```js
const brasileirao = require('campeonato-brasileiro-api');
const standings = await brasileirao.getStandings('c');
console.log(standings);
```
Exemplo de retorno:
```js
{
competition: {
code: 'c',
name: 'Campeonato Brasileiro Série C 2026'
},
grouped: false,
legends: [
{ id: 1, name: 'G8', color: '#0000ff' }
],
tables: [
{
id: 'overall',
name: 'Classificacao geral',
entries: [
{
position: 1,
team: { name: 'Amazonas', shortName: 'AMA' },
points: 12
}
]
}
]
}
```
### `getTable(serie, options?)`
#### Série A, B ou C
```js
const brasileirao = require('campeonato-brasileiro-api');
const table = await brasileirao.getTable('a');
console.log(table.entries[0]);
```
#### Série D com grupo
```js
const brasileirao = require('campeonato-brasileiro-api');
const table = await brasileirao.getTable('d', { group: 'A14' });
console.log(table.name);
console.log(table.entries[0].team.name);
```
Exemplo de retorno:
```js
{
id: 6014,
name: 'Grupo A14',
round: { number: 4, total: 10, label: '4a rodada' },
entries: [
{
position: 1,
team: {
id: 305,
name: 'XV de Piracicaba',
shortName: 'XVP',
badge: 'https://...'
},
points: 10
}
]
}
```
### `getGroups(serie, options?)`
```js
const brasileirao = require('campeonato-brasileiro-api');
const groups = await brasileirao.getGroups('d');
for (const group of groups) {
console.log(group.name, group.entries[0].team.name);
}
```
Exemplo de retorno:
```js
[
{
id: 5988,
name: 'Grupo A1',
entries: [
{ position: 1, team: { name: 'Nacional-AM' }, points: 9 }
]
},
{
id: 6014,
name: 'Grupo A14',
entries: [
{ position: 1, team: { name: 'XV de Piracicaba' }, points: 10 }
]
}
]
```
### `getRounds(serie, options?)`
#### Série A, B ou C
```js
const brasileirao = require('campeonato-brasileiro-api');
const rounds = await brasileirao.getRounds('a');
console.log(rounds.rounds[0].matches);
```
#### Série D com grupo
```js
const brasileirao = require('campeonato-brasileiro-api');
const rounds = await brasileirao.getRounds('d', { group: 'Grupo A1' });
console.log(rounds.rounds[0]);
```
Exemplo de retorno:
```js
{
competition: {
code: 'd',
name: 'Campeonato Brasileiro Série D 2026'
},
grouped: true,
rounds: [
{
id: 5988,
groupId: 5988,
groupName: 'Grupo A1',
number: 4,
total: 10,
label: '4a rodada',
matches: [
{
id: 351601,
status: 'scheduled',
venue: 'Ismael Benigno',
homeTeam: { name: 'Manauara' },
awayTeam: { name: 'Monte Roraima' },
score: { home: 2, away: 0, penalties: null }
}
]
}
]
}
```
### `getCurrentRound(serie, options?)`
É um alias de `getRounds()`:
```js
const brasileirao = require('campeonato-brasileiro-api');
const currentRound = await brasileirao.getCurrentRound('b');
console.log(currentRound.rounds[0].number);
```
### `tabela(serie, options?)`
Helper legado com shape próximo ao pacote original.
```js
const brasileirao = require('campeonato-brasileiro-api');
const table = await brasileirao.tabela('a');
console.log(table[0]);
```
Exemplo de retorno:
```js
[
{
nome: 'Palmeiras',
sigla: 'PAL',
escudo: 'https://...',
posicao: 1,
pontos: '32',
jogos: '13',
vitorias: '10',
empates: '2',
derrotas: '1',
golsPro: '23',
golsContra: '10',
saldoGols: '13',
percentual: '82'
}
]
```
### `rodadaAtual(serie, rodada?, options?)`
Helper legado para jogos da rodada atual.
```js
const brasileirao = require('campeonato-brasileiro-api');
const jogos = await brasileirao.rodadaAtual('a', 13);
console.log(jogos);
```
Exemplo de retorno:
```js
[
{
mandante: 'Botafogo',
placarMandante: 2,
visitante: 'Internacional',
placarVisitante: 2
},
{
mandante: 'Athletico-PR',
placarMandante: 3,
visitante: 'Vitória',
placarVisitante: 1
}
]
```
Na Série D:
```js
const brasileirao = require('campeonato-brasileiro-api');
const jogos = await brasileirao.rodadaAtual('d', 4, { group: 'A1' });
console.log(jogos);
```
## Série D
A Série D é agrupada por design:
- `getStandings('d')` retorna todas as tabelas dos grupos
- `getGroups('d')` é o atalho mais direto para esses grupos
- `getTable('d', { group })` exige um grupo
- `getRounds('d', { group })` retorna a rodada atual do grupo selecionado
O campo `group` aceita, por exemplo:
- `A1`
- `Grupo A1`
- o `id` numérico do grupo
## Options
Todos os métodos principais aceitam `options`.
- `url`: sobrescreve a URL da competição
- `html`: usa um HTML já carregado, sem fazer fetch
- `fetch`: injeta uma implementação customizada de fetch
- `headers`: headers extras para a requisição
- `signal`: `AbortSignal`
- `group`: seleciona um grupo na Série D
- `number`: valida a rodada esperada em `getRounds()`
### Exemplo com `html`
```js
const fs = require('node:fs');
const brasileirao = require('campeonato-brasileiro-api');
const html = fs.readFileSync('./fixtures/serie-a.html', 'utf8');
const data = await brasileirao.getCompetition('a', { html });
```
### Exemplo com `fetch` customizado
```js
import { getCompetition } from 'campeonato-brasileiro-api';
const data = await getCompetition('b', {
fetch: globalThis.fetch,
headers: {
'user-agent': 'my-app/1.0.0'
}
});
```
## Erros
Os métodos podem lançar `BrasileiroApiError`.
Principais códigos:
- `INVALID_SERIE`
- `FETCH_UNAVAILABLE`
- `FETCH_FAILED`
- `INVALID_RESPONSE`
- `GROUP_REQUIRED`
- `GROUP_NOT_FOUND`
- `ROUND_NOT_AVAILABLE`
Exemplo:
```js
const brasileirao = require('campeonato-brasileiro-api');
try {
await brasileirao.getTable('d');
} catch (error) {
console.log(error.name);
console.log(error.code);
console.log(error.message);
console.log(error.details);
}
```
## Especificação OpenAPI
Este repositório agora inclui uma especificação OpenAPI 3.0 de referência em [docs/openapi.json](docs/openapi.json).
Importante:
- a biblioteca não expõe um servidor HTTP por conta própria
- a spec descreve um contrato REST de referência para quem quiser criar um wrapper HTTP sobre o pacote
- o arquivo é compatível com Swagger UI, Redoc e ferramentas OpenAPI em geral
Rotas cobertas na spec:
- `GET /series`
- `GET /competitions/{serie}`
- `GET /competitions/{serie}/standings`
- `GET /competitions/{serie}/table`
- `GET /competitions/{serie}/groups`
- `GET /competitions/{serie}/rounds`
- `GET /competitions/{serie}/current-round`
- `GET /legacy/{serie}/tabela`
- `GET /legacy/{serie}/rodada-atual`
## Limitações atuais da fonte
A fonte atual expõe de forma estável a classificação e a rodada ativa da competição. O pacote valida `number`, mas não inventa histórico de rodadas que a página não entrega.
## Licença
MIT
## Aviso
Este projeto é fornecido apenas para fins educacionais.