Models

Pydantic models for typed access to API response records. The client returns raw dicts inside ApiResponse; convert each one with Model.model_validate(record):

from liquipydia import LiquipediaClient, Player

with LiquipediaClient("my-app") as client:
    response = client.players.list("dota2", limit=5)
    players = [Player.model_validate(record) for record in response.result]

Conventions

  • All fields are optional (type | None = None). LPDB endpoints can omit fields without notice, so models never raise on missing data.

  • Unknown fields are preserved via ConfigDict(extra="allow"). New API fields are accessible on the validated model even before this library is updated.

  • Models are standalone. They don’t reference the client or each other and can be reused for any dict that follows the LPDB schema.

Type aliases

Three reusable field types handle LPDB’s quirky null-encoding so consumers see clean None / date / datetime / dict values:

liquipydia._models.NullableDate

A date field that converts LPDB null sentinels ("0000-01-01", "") to None.

alias of Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]

liquipydia._models.NullableDatetime

A datetime field that converts LPDB null sentinels ("0000-01-01 00:00:00", "") to None.

alias of Annotated[datetime | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]

liquipydia._models.LpdbDict

A dict field that converts empty API lists ([]) to None.

alias of Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]

A handful of fields (e.g. stream on Match, earningsbyyear on Player) legitimately vary between dict and list shapes. Those use an explicit dict[str, Any] | list[Any] | None union rather than LpdbDict.

Internal base classes

The classes below are not part of the public API (they are prefixed with _). They are documented here only to make field inheritance visible — refer to the concrete model classes for day-to-day use.

class liquipydia._models._LpdbModel

Bases: BaseModel

Base model for LPDB v3 response records.

Provides common fields shared across most endpoints and allows extra fields since the API schema is not fully documented.

model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

pageid: int | None
pagename: str | None
namespace: int | None
objectname: str | None
wiki: str | None
class liquipydia._models._TeamTemplateBase

Bases: BaseModel

Base model for team template records.

Team template endpoints return a different field set from standard endpoints (no pageid, namespace, objectname, or wiki).

model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

template: str | None
page: str | None
name: str | None
shortname: str | None
bracketname: str | None
image: str | None
imagedark: str | None
legacyimage: str | None
legacyimagedark: str | None
imageurl: str | None
imagedarkurl: str | None
legacyimageurl: str | None
legacyimagedarkurl: str | None

Standard models

class liquipydia.Broadcaster

Bases: _LpdbModel

A broadcaster record from the /broadcasters endpoint.

id: str | None
name: str | None
page: str | None
position: str | None
language: str | None
flag: str | None
weight: int | None
date: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
parent: str | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.Company

Bases: _LpdbModel

A company record from the /company endpoint.

name: str | None
image: str | None
imageurl: str | None
imagedark: str | None
imagedarkurl: str | None
locations: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
parentcompany: str | None
sistercompany: str | None
industry: str | None
foundeddate: Annotated[datetime | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
defunctdate: Annotated[datetime | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
defunctfate: str | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.Datapoint

Bases: _LpdbModel

A datapoint record from the /datapoint endpoint.

type: str | None
name: str | None
information: str | None
image: str | None
imageurl: str | None
imagedark: str | None
imagedarkurl: str | None
date: Annotated[datetime | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Bases: _LpdbModel

An external media link record from the /externalmedialink endpoint.

title: str | None
translatedtitle: str | None
date: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
authors: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
language: str | None
publisher: str | None
type: str | None
extradata: dict[str, Any] | list[Any] | None
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.Match

Bases: _LpdbModel

A match record from the /match endpoint.

match2id: str | None
match2bracketid: str | None
status: str | None
winner: str | None
walkover: str | None
resulttype: str | None
finished: int | None
mode: str | None
type: str | None
section: str | None
game: str | None
patch: str | None
date: Annotated[datetime | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
dateexact: int | None
stream: dict[str, Any] | list[Any] | None
bestof: int | None
vod: str | None
tournament: str | None
parent: str | None
tickername: str | None
shortname: str | None
series: str | None
icon: str | None
iconurl: str | None
icondark: str | None
icondarkurl: str | None
liquipediatier: str | None
liquipediatiertype: str | None
publishertier: str | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
match2bracketdata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
match2opponents: list[Any] | None
match2games: list[Any] | None
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.Placement

Bases: _LpdbModel

A placement record from the /placement endpoint.

tournament: str | None
series: str | None
parent: str | None
imageurl: str | None
imagedarkurl: str | None
startdate: Annotated[datetime | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
date: Annotated[datetime | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
placement: str | None
prizemoney: int | None
individualprizemoney: int | None
prizepoolindex: int | None
weight: float | None
mode: str | None
type: str | None
liquipediatier: str | None
liquipediatiertype: str | None
publishertier: str | None
icon: str | None
iconurl: str | None
icondark: str | None
icondarkurl: str | None
game: str | None
lastvsdata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
opponentname: str | None
opponenttemplate: str | None
opponenttype: str | None
opponentplayers: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
qualifier: str | None
qualifierpage: str | None
qualifierurl: str | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.Player

Bases: _LpdbModel

A player record from the /player endpoint.

id: str | None
alternateid: str | None
name: str | None
localizedname: str | None
type: str | None
nationality: str | None
nationality2: str | None
nationality3: str | None
region: str | None
birthdate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
deathdate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
teampagename: str | None
teamtemplate: str | None
status: str | None
earnings: int | None
earningsbyyear: dict[str, Any] | list[Any] | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.Series

Bases: _LpdbModel

A series record from the /series endpoint.

name: str | None
abbreviation: str | None
image: str | None
imageurl: str | None
imagedark: str | None
imagedarkurl: str | None
icon: str | None
iconurl: str | None
icondark: str | None
icondarkurl: str | None
game: str | None
type: str | None
organizers: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
locations: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
prizepool: float | None
liquipediatier: str | None
liquipediatiertype: str | None
publishertier: str | None
launcheddate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
defunctdate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
defunctfate: str | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.SquadPlayer

Bases: _LpdbModel

A squad player record from the /squadplayer endpoint.

id: str | None
name: str | None
nationality: str | None
position: str | None
role: str | None
type: str | None
newteam: str | None
teamtemplate: str | None
newteamtemplate: str | None
status: str | None
joindate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
joindateref: str | None
leavedate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
leavedateref: str | None
inactivedate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
inactivedateref: str | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.StandingsEntry

Bases: _LpdbModel

A standings entry record from the /standingsentry endpoint.

parent: str | None
standingsindex: int | None
opponenttype: str | None
opponentname: str | None
opponenttemplate: str | None
opponentplayers: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
placement: int | None
definitestatus: str | None
currentstatus: str | None
placementchange: int | None
scoreboard: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
roundindex: int | None
slotindex: int | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.StandingsTable

Bases: _LpdbModel

A standings table record from the /standingstable endpoint.

parent: str | None
standingsindex: int | None
title: str | None
tournament: str | None
section: str | None
type: str | None
matches: dict[str, Any] | list[Any] | None
config: dict[str, Any] | list[Any] | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.Team

Bases: _LpdbModel

A team record from the /team endpoint.

name: str | None
locations: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
region: str | None
logourl: str | None
logodark: str | None
logodarkurl: str | None
textlesslogourl: str | None
textlesslogodarkurl: str | None
status: str | None
createdate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
disbanddate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
earnings: int | None
earningsbyyear: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
template: str | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.Tournament

Bases: _LpdbModel

A tournament record from the /tournament endpoint.

name: str | None
shortname: str | None
tickername: str | None
banner: str | None
bannerurl: str | None
bannerdark: str | None
bannerdarkurl: str | None
icon: str | None
iconurl: str | None
icondark: str | None
icondarkurl: str | None
seriespage: str | None
serieslist: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
previous: str | None
previous2: str | None
next: str | None
next2: str | None
game: str | None
mode: str | None
patch: str | None
endpatch: str | None
type: str | None
organizers: str | None
startdate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
enddate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
sortdate: Annotated[date | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
locations: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
prizepool: float | None
participantsnumber: int | None
liquipediatier: str | None
liquipediatiertype: str | None
publishertier: str | None
status: str | None
maps: str | None
format: str | None
sponsors: str | None
extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.Transfer

Bases: _LpdbModel

A transfer record from the /transfer endpoint.

staticid: str | None
player: str | None
nationality: str | None
fromteam: str | None
toteam: str | None
fromteamtemplate: str | None
toteamtemplate: str | None
role1: str | None
role2: str | None
reference: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]
date: Annotated[datetime | None, BeforeValidator(func=_coerce_null_date, json_schema_input_type=PydanticUndefined)]
wholeteam: int | None
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

extradata: Annotated[dict[str, Any] | None, BeforeValidator(func=_coerce_empty_list_to_none, json_schema_input_type=PydanticUndefined)]

Team template models

class liquipydia.TeamTemplate

Bases: _TeamTemplateBase

A team template record from the /teamtemplate endpoint.

model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class liquipydia.TeamTemplateList

Bases: _TeamTemplateBase

A team template list record from the /teamtemplatelist endpoint.

model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].