---
title: Padel API
description: Professional padel — tournaments across the FIP Tour, matches with set-by-set scores, and pairs with their own Elo rating.
badge: pro
---

# Padel API

Padel is played in pairs, and the pair is the unit that competes. Two good
players who have been together three months are not the same team as the same
two freshly paired, so everything here — the rating, the record, the
head-to-head — belongs to the **pair**, not to the individual. The players are
there too, with their world ranking, because a pair is made of two of them.

Base URL: `https://sports.bzzoiro.com/padel/api/v2/`

## What this covers, and what it does not

The feed carries tournaments, draws, and matches with a set-by-set score.
It does **not** carry match statistics, betting odds or point-by-point — none
of those exist upstream for padel, at any source we know of. There is no
`/odds/` route and no `/predictions/` route here, because publishing an empty
endpoint would promise data that does not exist.

History starts in **March 2026**. That is not where our collection begins; it
is where the sport's coverage begins upstream. Nothing earlier is available to
anyone.

Draws are published on the day of play. A tournament's matches typically
appear a few hours before they start, so the schedule is thin more than a day
out — that is the tour's publishing rhythm, not a gap on our side.

## Access

Requires the **Sports Addon** ($5/month) — it unlocks the tennis, padel, CS2,
darts, hockey, basketball and horse racing APIs plus their MCP servers. Get it
at [/addons/](/addons/). You also need a free account token from
[/register/](/register/).

```bash
Authorization: Token YOUR_API_KEY
```

List endpoints paginate with `limit` (default 50, max 200) and `offset`, and
return `{count, next, previous, results}`.

## Endpoints

| Endpoint | Description |
|---|---|
| `GET /padel/api/v2/tournaments/` | List tournaments, most recent first |
| `GET /padel/api/v2/tournaments/{id}/` | Tournament detail with match count |
| `GET /padel/api/v2/matches/` | List matches |
| `GET /padel/api/v2/matches/live/` | Matches in play right now |
| `GET /padel/api/v2/matches/{id}/` | Match detail |
| `GET /padel/api/v2/pairs/` | List/search pairs by Elo |
| `GET /padel/api/v2/pairs/{id}/` | Pair detail with record |
| `GET /padel/api/v2/players/` | List/search players |
| `GET /padel/api/v2/players/{id}/` | Player detail |

There is also an MCP server at `/padel/mcp/` with seven tools:
`list_tournaments`, `list_pairs`, `search_pairs`, `search_players`,
`list_matches`, `get_match` and `get_pair`.

## Tournaments

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `category` | string | Circuit, e.g. `Cupra FIP Tour` |
| `gender` | string | `M` or `F` |
| `limit` / `offset` | int | Pagination |

`start_date` and `end_date` are derived from the tournament's matches — the
tournament itself carries no dates upstream — and are `null` until at least
one match is known. The list is ordered by `end_date`, newest first, because
the circuit reuses tournament names every season and an alphabetical list
mixes editions.

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/padel/api/v2/tournaments/?gender=F&limit=1"
```

```json
{"count": 256, "results": [
  {"id": 188, "name": "FIP Platinum Lyon Women - Qualification",
   "category": "Cupra FIP Tour", "gender": "F",
   "start_date": "2026-09-22", "end_date": "2026-09-22"}
]}
```

## Matches

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `status` | string | See the status table below |
| `tournament_id` | int | Filter by tournament |
| `pair_id` | int | Matches involving this pair, either side |
| `limit` / `offset` | int | Pagination |

### Status values

| Value | Meaning |
|---|---|
| `scheduled` | Not started |
| `live` | In play |
| `finished` | Played to a result |
| `walkover` | One pair did not play |
| `retired` | Abandoned mid-match |
| `cancelled` / `postponed` | As published upstream |
| `unresolved` | **Ours, not theirs.** The scheduled time passed and no result was ever published |

`unresolved` deserves a note, because it will be a meaningful share of any
full archive you pull. The tour publishes a draw with provisional ids and
republishes the whole thing every time the order of play changes, without
resolving the old entries — the same Round of 32 can leave six rows behind,
none with a score. Calling those `scheduled` forever would be wrong, and
inventing a result would be worse. `unresolved` says exactly what is known:
that we never learned how it ended. **Filter them out when counting meetings
or building a record** — they are not matches that were played.

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/padel/api/v2/matches/?status=finished&limit=1"
```

```json
{"count": 5264, "results": [
  {"id": 4168,
   "tournament": {"id": 89, "name": "FIP Bronze QNB CUP Izmir Women - Main Draw",
                  "category": "Cupra FIP Tour", "gender": "F"},
   "home_pair": {"id": 1574, "name": "M. Portillo Perez / N. Sluzhiteleva",
                 "country_code": "", "elo_rating": 1549.7,
                 "players": [
                   {"id": 1086, "name": "Maria Portillo Perez",
                    "country_code": "ES", "country_name": "Spain", "ranking": 84},
                   {"id": 358, "name": "Nika Sluzhiteleva",
                    "country_code": "RU", "country_name": "Russia", "ranking": 166}]},
   "away_pair": {"id": 215, "name": "R. Lopez Lopez / C. Rose", "elo_rating": 1533.1,
                 "players": []},
   "match_date": "2026-09-19T09:00:00Z", "status": "finished",
   "round_name": "Round of 16",
   "home_sets": 2, "away_sets": 0,
   "sets_detail": [{"set": 1, "home": 6, "away": 3},
                   {"set": 2, "home": 6, "away": 4}],
   "home_games": 12, "away_games": 7,
   "winner_pair_id": 1574}
]}
```

`sets_detail` is the per-set game score in order. `winner_pair_id` matches
`home_pair.id` or `away_pair.id`, and is `null` until the match is decided.

## Pairs

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `search` | string | Pair name search |
| `player_id` | int | Every pair this player has been part of |
| `limit` / `offset` | int | Pagination |

Ordered by `elo_rating`, highest first.

```json
{"id": 46, "name": "J. Collantes Guijo / A. Martinez Lopez",
 "country_code": "", "elo_rating": 1695.3, "elo_peak": 1695.3,
 "players": [
   {"id": 90, "name": "Javier Collantes Guijo", "country_code": "ES",
    "country_name": "Spain", "ranking": 283},
   {"id": 91, "name": "Asier Martinez Lopez", "country_code": "ES",
    "country_name": "Spain", "ranking": 220}],
 "matches_played": 12, "matches_won": 11, "win_rate": 0.917}
```

### About the Elo

The rating is recomputed from the whole archive on every run, never
incrementally: matches arrive out of order — the calendar first, the back
catalogue after — and an incremental rating that receives an old match after a
new one stays wrong forever.

There is **no home advantage** in it. In a draw, "home" is which side of the
bracket a pair came out of, not where they are playing. Adding an advantage
there would be inventing one.

A pair at exactly 1500 with matches played is not a bug: 1500 is the starting
rating, and winning one and losing one against evenly matched opponents
returns you to it.

`country_code` on a pair is filled only when both players share a nationality.
A mixed pair has no flag, which is the truth — it is left empty rather than
guessing one of the two.

## Players

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `search` | string | Name search |
| `limit` / `offset` | int | Pagination |

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/padel/api/v2/players/?search=coello"
```

```json
{"count": 2, "results": [
  {"id": 1250, "name": "Arturo Coello", "country_code": "ES",
   "country_name": "Spain", "ranking": 1},
  {"id": 1107, "name": "Rodrigo Coello Manso", "country_code": "ES",
   "country_name": "Spain", "ranking": 104}
]}
```

`ranking` is the individual world ranking as last seen. It arrives inside the
team payload rather than from a rankings endpoint, so there is no ranking
history to query and it is `null` for players who have not appeared with one.

## Photos

Player photos are served through the image proxy:

```
https://sports.bzzoiro.com/img/padel/player/{id}/
```

Use the `id` from this API. Add `?bg=transparent` to strip the white border.
