Skip to contents

Per club, the players joining and leaving, one row per move with its direction (BBL only).

Endpoint: GET https://api.basketball-bundesliga.de/transfers/teams

Usage

scb_transfers_teams()

Value

A wehoop_data tibble: Per club, the players joining and leaving, one row per move with its direction (BBL only). An empty valid answer raises wehoop_no_data; the columns are always these, in this order (sdv-py scb_transfers_teams):

col_nametypedescription
team_idcharacterClub id, a string; equal to season_team_id in every sample. Joins to scb_team and scb_season_teams.
directioncharacterjoining or leaving: whether team_id is the destination or the source of the move.
leaguecharacterLeague the row belongs to: bbl (men) or dbbl (women); BBL and DBBL game ids overlap, so a game is (league, game_id).
transfer_datecharacterDate of the transfer, YYYY-MM-DD (the API's sortingDate).
season_player_idcharacterSeason-player id: one player's engagement with one club (kept across seasons while he stays, new after a move). Joins box-score lines, actions, records and scb_season_player.
real_player_idintegerGlobal person id (integer): the same player across clubs and seasons. Join players across seasons on this.
first_namecharacterPlayer's given name.
last_namecharacterPlayer's family name.
positioncharacterPosition: POINT_GUARD, SHOOTING_GUARD, SMALL_FORWARD, POWER_FORWARD, CENTER.
source_team_idcharacterClub id the player left; null when the source is not a league club.
source_team_namecharacterName of the club the player left (the free-text field, else the short club name).
destination_team_idcharacterClub id the player joined; null when the destination is not a league club.
destination_team_namecharacterName of the club the player joined (the free-text field, else the short club name).

Details

  • Unofficial use of a public source: these wrappers read the front-end API of the German Bundesliga sites (easycredit-bbl.de, toyota-dbbl.de), run by SCB; payloads are not redistributed as release assets.

  • Legal notice: the BBL Impressum forbids storing BBL content (Inhalte) in an information system without BBL's written permission. That is a copyright term, not a robots rule (the API host has no robots.txt). The owner reviewed it and accepted the intake (2026-10-12 ruling); keep requests slow (the runtime waits at least 1 s per host) and raise any published data release with the owner. The DBBL host is the same operator and API; its site notice was not separately reviewed.

  • Both hosts need two headers: a constant x-api-key and an x-api-secret that rotates. The runtime derives the secret on first use from the key embedded in an easycredit-bbl.de page (reversed, : turned into -) and never logs or returns it. The derivation was reverse-engineered from observed requests and responses and has not been checked against the site's own front-end code; if the site changes how it signs requests, every call fails with wehoop_asset_fetch.

  • Id key spaces: seasonId is the START year (2025 = 2025-26), so a wrapper's END-year season is sent as season - 1. Teams are keyed by teamId (seasonTeamId equals it in every sample). seasonPlayerId is per player per season and per club (a player traded mid-season has two); realPlayerId is the person. playerId is ambiguous (the seasonPlayerId in box scores, records and /season-players; the person in /transfers). Game ids are strings.

  • Errors are classed conditions: wehoop_no_data (404, 204, a 400 "not a valid" id, no rows, a box score of a game not yet started), wehoop_bad_request (a bad argument, another 400 / 422) and wehoop_asset_fetch (a refused secret after one re-derive, any other non-2xx, an HTML / non-JSON / error-shaped body, a truncated page, a body for another game, season, club or league, a box score still in play), all inheriting wehoop_error. Wrappers raise; they never return an empty frame.