Endfield Client API
Complete reference for the Endfield Python SDK. Fetch player profiles, character data, game statistics, and factory blueprints from the Endfield game API.
Methods
The main Endfield client class provides all functionality for querying player data and game information.
def __init__(session=None, debug=False, timeout=5, proxy_pool=None)
Initialize the Endfield client.
| session | Optional[aiohttp.ClientSession] |
| debug | bool — Enable debug logging. Default: False |
| timeout | int — Timeout in seconds. Default: 5 |
| proxy_pool | Optional[ProxyPool] — Proxy pool for auth requests |
async __aenter__()
Async context manager entry.
async __aexit__(*_) → None
Async context manager exit. Ensures the session is closed.
async close() → None
Close the internal aiohttp ClientSession if it was created internally. A session passed in via the session constructor argument is left open — you own its lifetime.
async verify_user(token: str) → User | None
Verify an authentication token and retrieve the associated Skport account information.
Parameters
| token | str — Authentication token |
Returns
| result | User | None |
async get_showcase(uid: int | str) → ShowcaseData
Retrieve showcase data (profile and characters) for a specific user ID. Every returned character has both stats and detailed_stats populated. Raw upstream responses are cached for 5 minutes per UID, and a failed decode is retried up to 3 times with exponential backoff.
Parameters
| uid | int | str — User ID (UID) |
Returns
| showcase | ShowcaseData |
async get_character_showcase(uid: int | str, index: int = 0) → CharacterData
Retrieve character showcase data for a specific user ID and character index.
Parameters
| uid | int | str — User ID (UID) |
| index | int — Character index. Default: 0 |
Returns
| character | CharacterData |
Raises
| CharacterNotFoundError | error — index is negative or beyond the number of showcased characters |
async get_profile(uid: int | str) → PlayerProfile
Retrieve only the player profile data for a specific user ID.
Parameters
| uid | int | str — User ID (UID) |
Returns
| profile | PlayerProfile |
def get_detailed_stats(char_data: CharacterData) → ComputedStatsWithDetails
Flatten a character's ComputedStats into a display-ready list, attaching a human-readable name and icon URL to each stat and flagging which entries are the character's main and sub attributes. Stats left as None on ComputedStats are omitted. Called automatically by get_showcase, get_character_showcase, and get_game_character, which assign the result to CharacterData.detailed_stats.
Parameters
| char_data | CharacterData — Character to compute; requires stats to be populated |
Returns
| stats | ComputedStatsWithDetails — Wrapper around all: list[StatDetail] |
async get_game_stats(token: str, server: int = 3) → GameStats | None
Fetch game statistics using an authentication token. Results are cached per token for 5 minutes. If a ProxyPool was passed to the constructor, the request is routed through it. Returns None on any error rather than raising.
Parameters
| token | str — Authentication token |
| server | int — Server ID. Default: 3 |
Returns
| stats | GameStats | None |
async get_game_character(token: str, char_id: str, gender: Literal["1", "2"] = "1") → CharacterData
Fetch a specific character from the authenticated user's roster and convert it into the same CharacterData shape returned by the showcase endpoints. detailed_stats is populated automatically.
Parameters
| token | str — Authentication token |
| char_id | str — Character hashed ID (use get_all_characters) |
| gender | Literal["1", "2"] — Endministrator gender used to pick splash art and icons: "1" male, "2" female. Only affects the main character. Default: "1" |
Returns
| character | CharacterData |
async get_all_characters(token: str) → AllCharacters | None
Fetch all characters from the authenticated user's roster.
Parameters
| token | str — Authentication token |
Returns
| result | AllCharacters | None |
async perform_daily_sign(token: str) → str
Perform daily sign-in using an authentication token.
Parameters
| token | str — Authentication token |
Returns
| message | str — Sign-in result message |
async get_monument(token: str) → IndieHardData | None
Fetch Monument (Indie Hard) progression for the authenticated user — dungeon groups, per-dungeon best records, enemy rosters, and the associated achievement plating.
Parameters
| token | str — Authentication token |
Returns
| monument | IndieHardData | None |
async check_for_updates() → Any
Check for available asset updates.
async update_assets() → None
Download and apply asset updates.
async get_factory_blueprints(region="Both", item="all", start=0, end=10) → FactoryPlans
Fetch factory blueprints from the Endfieldtools API with optional filtering and pagination. Results are sorted by view count. The local blueprint cache refreshes if it is more than 2 days old.
Parameters
| region | Literal["Americas/Europe", "Asia", "Both"] — Default: "Both" |
| item | Literal["all"] | items — Output-item slug to filter by (e.g. "xiranite", "heavy-xiranite"), or "all". Default: "all" |
| start | int — Pagination start index, 0-based. Default: 0 |
| end | int — Pagination end index, exclusive. Default: 10 |
Returns
| plans | FactoryPlans |
Data Models
Every model is a Pydantic BaseModel, so each supports .model_dump(), .model_dump_json() and attribute access. Fields marked with a default are optional; everything else is required. The badge on each model shows the module it lives in.
Showcase & Profile
ShowcaseData
Root object returned by get_showcase().
Attributes
| Name | Type | Description |
|---|---|---|
profile | PlayerProfile | Player profile and statistics |
characters | list[CharacterData] | Showcased characters, each with stats and detailed_stats already populated |
PlayerProfile
Player profile information. Returned on its own by get_profile(), and as ShowcaseData.profile.
Attributes
| Name | Type | Description |
|---|---|---|
uid | str | Player UID |
name | str | Player name |
short_id | str | Short identifier, the friend code shown in-game |
signature | str | Player signature/bio |
avatar_url | str | Avatar image URL. Empty string if the avatar could not be resolved |
bg_url | str | Business-card background URL |
frame_url | str | None | Avatar frame URL. Default: None |
adventure_level | int | Adventure level |
world_level | int | World level |
char_count | int | Total characters owned |
weapon_count | int | Total weapons owned |
doc_count | int | Total documents collected |
domain_progress | list[DomainProgress] | Per-domain development levels |
medals | Medals | Displayed achievement medals |
characters | list[ProfileCharacter] | Business-card display characters, in display order |
ttl | int | None | Cache time-to-live in seconds. Default: None |
ProfileCharacter
Lightweight character entry shown on a player's business card. For the full build, use CharacterData from ShowcaseData.characters.
Attributes
| Name | Type | Description |
|---|---|---|
template_id | int | Numeric character template ID |
str_id | str | String identifier, e.g. "chr_0030_zhuangfy" |
name | str | Resolved character name, or "unknown" |
level | int | Current level |
potential_level | int | Potential level |
rarity | int | Rarity tier |
element | str | Elemental affinity |
profession | str | Class/profession type |
splash_url | str | Splash art URL |
round_icon_url | str | Round icon URL |
DomainProgress
Development level for a single domain.
Attributes
| Name | Type | Description |
|---|---|---|
domain_id | str | Domain identifier |
level | int | Development level |
name | str | Resolved domain name. Default: "unknown" |
Medals
Wrapper around the player's displayed medals.
Attributes
| Name | Type | Description |
|---|---|---|
medals | list[Medal] | Medals the player has chosen to display |
Medal
A single achievement medal at the level the player has reached.
Attributes
| Name | Type | Description |
|---|---|---|
index | int | Display slot on the business card. 0 if the medal is not in the display list |
name | str | Medal name, or "unknown" |
description | str | Unlock condition text for the reached level |
icon_url | str | Icon URL for the reached level |
Character
CharacterData
Full character build — identity, base attributes, weapon, relics, skills, talents and computed stats. Returned by get_character_showcase() and get_game_character(), and found in ShowcaseData.characters.
Attributes
| Name | Type | Description |
|---|---|---|
template_id | int | Numeric character template ID. For the Endministrator this is the gender-specific display ID (22 male / 29 female), not the raw 38 |
str_id | str | String identifier, e.g. "chr_0030_zhuangfy" |
name | str | Character name |
rarity | int | Rarity tier |
element | str | Elemental affinity |
profession | str | Class/profession type |
weapon_type | str | Weapon type the character can equip |
level | int | Current level |
potential_level | int | Potential level, drives talents.potential_attributes |
splash_url | str | Splash art URL |
bg_url | str | Character background art URL |
round_icon_url | str | Round icon URL |
main_attribute | CharAttr | Primary scaling attribute |
sub_attribute | CharAttr | Secondary scaling attribute |
base_atk | BaseAttr | Base attack at the current level (attribute ID "2") |
base_hp | BaseAttr | Base HP at the current level (attribute ID "1") |
base_attribute | list[BaseAttr] | Remaining level-scaled base attributes. Default: [] |
weapon | WeaponData | None | Equipped weapon. Default: None |
equips | list[EquipData] | Equipped relics. Default: [] |
suit_sets | SuitSet | None | Active relic set bonus. None unless at least 3 relics share a suit_id. Default: None |
skills | SkillMeta | Skill loadout and levels |
talents | TalentInfo | None | Talent tree state. Default: None |
stats | ComputedStats | None | Final stats after weapon, relics and talents. Default: None |
detailed_stats | ComputedStatsWithDetails | None | Display-ready form of stats. Default: None |
CharAttr
Identifies a character's main or sub scaling attribute. Carries no value — the value lives in ComputedStats.
Attributes
| Name | Type | Description |
|---|---|---|
attri_id | str | Attribute ID |
attri_name | str | Internal attribute name, or "unknown" |
url | str | Attribute icon URL. Note the field is url, not icon_url |
BaseAttr
A base attribute already scaled to the character's current level.
Attributes
| Name | Type | Description |
|---|---|---|
attri_id | str | Attribute ID |
attri_name | str | Internal attribute name, e.g. "Atk_base" |
url | str | Attribute icon URL |
value | int | float | Value at the current level |
is_float | bool | True when value is a ratio rather than a flat number. Default: False |
SkillMeta
A character's skill loadout. The four ID fields name which entry in skills fills each slot.
Attributes
| Name | Type | Description |
|---|---|---|
normal_skill | str | Battle skill ID |
ultimate_skill | str | Ultimate skill ID |
combo_skill | str | Combo skill ID |
disp_normal_atk_skill | str | Displayed normal-attack skill ID |
skills | list[SkillInfo] | Every skill with its level. Skills missing from the asset map are skipped |
SkillInfo
A single skill and its level state.
Attributes
| Name | Type | Description |
|---|---|---|
skill_id | str | Skill identifier |
icon_url | str | Skill icon URL |
element | str | Damage element of the skill, or "unknown" |
level | int | Current skill level |
max_level | int | Maximum reachable level |
enhanced_level | int | Enhancement tier applied on top of level |
TalentInfo
Unlocked state of a character's talent tree.
Attributes
| Name | Type | Description |
|---|---|---|
latest_break_node | str | Most recently unlocked breakthrough node |
attr_nodes | AttrNode | Aggregate of every unlocked attribute node, as a single object rather than a list |
passive_nodes | list[TalentPassiveNode] | Unlocked passive skill nodes |
factory_nodes | list[TalentFactoryNode] | Unlocked factory skill nodes |
potential_attributes | list[PotentialAttributes] | Bonuses granted by potential. Empty when potential_level is 0. Default: [] |
AttrNode
Rolled-up attribute gain from the talent tree. All unlocked attribute nodes contribute to one AttrNode keyed on the character's primary talent attribute.
Attributes
| Name | Type | Description |
|---|---|---|
attri_id | str | Attribute ID, or "0" if it could not be resolved |
attri_name | str | Internal attribute name, or "unknown" |
formula | str | How the value applies. Default: "BaseAddition" |
icon_url | str | Attribute icon URL |
values | list[int] | Per-node contributions, in unlock order |
total_value | int | Sum of values |
level | int | Number of unlocked attribute nodes, i.e. len(values) |
TalentPassiveNode
An unlocked passive node in the talent tree.
Attributes
| Name | Type | Description |
|---|---|---|
node_id | str | Node identifier |
icon_url | str | Node icon URL |
level | int | Node tier, 1–3 |
index | int | Position within the talent tree |
is_max | bool | True when level >= 2. Default: False |
type | int | Node type code |
TalentFactoryNode
An unlocked factory node in the talent tree. Same shape as TalentPassiveNode, kept separate so the two node kinds stay distinguishable.
Attributes
| Name | Type | Description |
|---|---|---|
node_id | str | Node identifier |
icon_url | str | Node icon URL |
level | int | Node tier |
index | int | Position within the talent tree |
is_max | bool | True when level >= 2. Default: False |
type | int | Node type code |
PotentialAttributes
One potential tier's worth of stat bonuses. Only tiers at or below the character's potential_level are included.
Attributes
| Name | Type | Description |
|---|---|---|
required_potential_level | int | Potential level that unlocks this tier |
attributes | list[PoteAtrri] | Bonuses granted at this tier |
PoteAtrri
A single stat bonus from potential. The class name is spelled PoteAtrri in the source.
Attributes
| Name | Type | Description |
|---|---|---|
attri_id | str | Attribute ID |
attri_name | str | Internal attribute name, or "unknown" |
icon_url | str | Attribute icon URL |
value | int | float | Bonus amount |
is_float | bool | True when value is a ratio. Default: False |
formula | str | How the bonus applies, or "unknown" |
Stats
ComputedStats
Final character stats after weapon, relics, set bonuses, talents and potential are applied. Fields typed float | None are None when the character has no source for that bonus — get_detailed_stats() omits those from its output.
Two field names are deliberately off: defense (because def is a Python keyword) and str (Strength — it shadows the str builtin as an attribute name, though only inside the model).
Attributes
| Name | Type | Description |
|---|---|---|
str | int | Strength |
agi | int | Agility |
wisd | int | Intellect |
will | int | Will |
hp | int | HP |
atk | int | Attack |
defense | int | Defense |
crit_rate | float | Critical Rate, percent. Default: 5.0 |
crit_dmg | float | Critical DMG, percent. Default: 50.0 |
arts_intensity | float | Arts Intensity |
healing_received_bonus | float | Treatment Received Bonus. Default: 0.0 |
ultimate_gain_efficiency | float | Ultimate Gain Efficiency. Default: 100.0 |
healing_bonus | float | None | Treatment Bonus. Default: None |
normal_atk_dmg_bonus | float | None | Basic Attack DMG Bonus. Default: None |
normal_skill_dmg_bonus | float | None | Battle Skill DMG Bonus. Default: None |
combo_skill_dmg_bonus | float | None | Combo Skill DMG Bonus. Default: None |
ult_skill_dmg_bonus | float | None | Ultimate DMG Bonus. Default: None |
physical_dmg_bonus | float | None | Physical DMG Bonus. Default: None |
fire_dmg_bonus | float | None | Heat DMG Bonus. Default: None |
pulse_dmg_bonus | float | None | Electric DMG Bonus. Default: None |
cryst_dmg_bonus | float | None | Cryo DMG Bonus. Default: None |
natural_dmg_bonus | float | None | Nature DMG Bonus. Default: None |
ether_dmg_bonus | float | None | Ether DMG Bonus. Default: None |
infliction_enhance | float | None | Arts Intensity from infliction sources. Default: None |
ComputedStatsWithDetails
Display-ready wrapper around ComputedStats, returned by get_detailed_stats().
Attributes
| Name | Type | Description |
|---|---|---|
all | list[StatDetail] | One entry per non-None stat |
StatDetail
A single stat with everything needed to render it.
Attributes
| Name | Type | Description |
|---|---|---|
value | int | float | None | Stat value |
icon_url | str | Attribute icon URL |
stat_id | str | Attribute ID, or "unknown" |
name | str | Display name, e.g. "Critical Rate", "Heat DMG Bonus" |
main_attri | bool | True if this is the character's main attribute. Default: False |
sub_attri | bool | True if this is the character's sub attribute. Default: False |
Weapon
WeaponData
Equipped weapon, found at CharacterData.weapon.
Attributes
| Name | Type | Description |
|---|---|---|
weapon_id | str | Weapon template ID as a string |
name | str | Weapon name |
rarity | int | Rarity tier |
weapon_type | str | Weapon category, or "unknown" |
level | int | Current level |
refine_lv | int | Refinement level; raises skill level bounds when above 0 |
breakthrough_lv | int | Breakthrough level; sets the base skill level bounds |
base_atk | float | Base attack at the current level, rounded to 3 decimals |
skill_levels | list[int] | Convenience copy of each entry's current_lvl, in the same order as skills |
icon_url | str | Weapon icon URL |
skills | list[WeaponSkill] | Weapon passives with resolved values |
main_stat | MainStat | Primary stat line, always base attack |
gem | Gem | None | Attached gem, or None. Required field — must be present, may be null |
WeaponSkill
A weapon passive at its current level.
Five fields change shape. prop_id, formula, prop_name, icon_url and value are scalars when the skill affects one property, and equal-length lists when it affects several. Branch on isinstance(skill.prop_id, list) before reading them.
Attributes
| Name | Type | Description |
|---|---|---|
skill_id | str | Skill identifier |
tag_id | str | Effect tag identifier |
prop_id | str | list[str] | Affected property ID(s) |
base_lvl | int | Lower level bound from breakthrough plus refinement |
max_lvl | int | Upper level bound from breakthrough plus refinement |
current_lvl | int | Effective level, base_lvl plus gem cost, clamped to max_lvl |
formula | str | list[str] | How the value applies |
prop_name | str | list[str] | Internal property name(s) |
icon_url | str | list[str] | Attribute icon URL(s) |
value | float | list[float] | Value(s) at current_lvl |
MainStat
A weapon's primary stat line. Every field except value is a constant default, since the main stat is always base attack.
Attributes
| Name | Type | Description |
|---|---|---|
value | int | Base attack at the weapon's current level |
prop_id | str | Default: "2" |
prop_name | str | Default: "Atk_base" |
formula | str | Default: "BaseAddition" |
icon_url | str | Default: "https://enka.network/ui/ef/attributeicon/Atk.png" |
Gem
A gem socketed into a weapon. Gem terms raise the effective level of the weapon's skills.
Attributes
| Name | Type | Description |
|---|---|---|
rarity | int | Rarity tier, parsed from the gem's icon filename. Falls back to 3 |
name | str | Name of the last applied term. Empty string if the gem has no terms |
inner_icon_url | str | Term tag icon URL. Empty string if unresolved |
cover_icon_url | str | Gem cover icon URL. Empty string if unresolved |
Equipment
EquipData
A single equipped relic. Relics sharing a suit_id form a set; 3 or more activate the SuitSet bonus.
Attributes
| Name | Type | Description |
|---|---|---|
slot_id | int | Equipment slot |
template_id | int | Relic template ID |
rarity | int | Rarity tier. Falls back to 5 |
suit_id | str | Suit set identifier |
icon_url | str | Relic icon URL |
attr_modifiers | list[AttrModifier] | Main and sub stats. Empty if the relic has no modifiers in the asset data |
AttrModifier
One stat line on a relic.
Attributes
| Name | Type | Description |
|---|---|---|
index | int | Position in the relic's modifier array |
attr_type | int | Attribute ID as an integer |
attr_name | str | Internal attribute name, or "unknown" |
formula | str | One of "BaseAddition", "BaseMultiplier", "BaseFinalMultiplier", or "unknown" |
enhance_level | int | 1-based enhancement level of this line |
value | float | Value at enhance_level, rounded to 3 decimals |
icon | str | Attribute icon URL. Note the field is icon, not icon_url |
SuitSet
Relic set bonus, at CharacterData.suit_sets. Only ever populated for a set with 3 or more pieces equipped; otherwise the field is None.
Attributes
| Name | Type | Description |
|---|---|---|
suit_id | str | Suit set identifier |
name | str | None | Set name hash. Default: None |
icon_url | str | Set icon URL |
pieces_equipped | int | Number of pieces from this set that are equipped |
is_active | bool | Whether the set bonus is active |
active_bonus | SuitSetEffect | None | Bonus effect, populated only when is_active. Default: None |
SuitSetEffect
The effect granted by an active relic set.
Attributes
| Name | Type | Description |
|---|---|---|
tagid | str | None | Effect tag identifier. All lowercase, not tag_id. Default: None |
propmap | list[PropMap] | None | Stat changes, scaled to the number of pieces equipped. Default: None |
PropMap
One stat change contributed by a set bonus.
Attributes
| Name | Type | Description |
|---|---|---|
prop_id | str | Property ID |
prop_name | str | Internal property name, or "unknown" |
value | float | Value for the current piece count |
formula | str | How the value applies, or "unknown" |
Auth
User
Skport account information returned by verify_user().
Attributes
| Name | Type | Description |
|---|---|---|
uid | int | In-game UID |
skport_id | int | Skport account ID |
skport_name | str | Skport account name |
server_id | int | Home server ID |
cred | str | None | Session credential derived from the token. Default: None |
sign_token | str | None | Token used for request signing. Default: None |
sk_role | str | None | Skport role identifier. Default: None |
AllCharacters
Roster returned by get_all_characters(). This is a wrapper, not a list — iterate result.characters.
Attributes
| Name | Type | Description |
|---|---|---|
characters | list[Character] | Every character the account owns |
total | int | Total character count. Default: 0 |
Character
A roster entry. Pass char_id to get_game_character() to fetch the full CharacterData build.
Attributes
| Name | Type | Description |
|---|---|---|
char_id | str | Hashed character identifier |
name | str | Character name |
level | int | Current level |
potential_level | int | Potential level |
evolve_phase | int | Ascension phase |
rarity | int | Rarity tier |
square_icon | str | Square avatar icon URL |
proffesion | str | Class/profession type, uppercase. The field is spelled proffesion — two f's, one s. It does not match ProfileCharacter.profession or CharacterData.profession |
element | str | Elemental affinity, first letter uppercase |
rect_icon | str | Rectangular portrait icon URL |
splash_icon | str | Full splash art URL |
owned_at | int | Unix timestamp of when the character was obtained |
Game Stats
GameStats
Authenticated account statistics, returned by get_game_stats(). Every attribute is a nested model, so use attribute access rather than dict subscripting.
Attributes
| Name | Type | Description |
|---|---|---|
regions | Regions | Factory and settlement state per region |
sanity_point | SanityPoint | Stamina and recovery time |
battle_pass | BattlePass | Battle pass progress |
daily_points | DailyPoints | Daily activity points |
weekly_points | WeeklyPoints | Weekly challenge points |
SanityPoint
Stamina state.
Attributes
| Name | Type | Description |
|---|---|---|
current | int | Current sanity |
max | int | Maximum sanity |
full_recover_at | datetime | None | When sanity refills completely. Required field — must be present, may be null |
BattlePass
Battle pass progress.
Attributes
| Name | Type | Description |
|---|---|---|
max_level | int | Highest reachable level this season |
current_level | int | Current level |
DailyPoints
Daily activity points.
Attributes
| Name | Type | Description |
|---|---|---|
current | int | Points earned today |
max | int | Daily maximum |
WeeklyPoints
Weekly challenge points. Note the field names differ from DailyPoints.
Attributes
| Name | Type | Description |
|---|---|---|
score | int | Points earned this week |
total | int | Weekly maximum |
Regions
Wrapper around the account's regions.
Attributes
| Name | Type | Description |
|---|---|---|
all | list[Region] | Every region the account has unlocked. Reached as stats.regions.all |
Region
Factory and settlement state for one region.
Attributes
| Name | Type | Description |
|---|---|---|
region_id | str | Region identifier |
region_name | str | Region display name |
factory_level | int | Factory level in this region |
factory_money | FactoryMoney | Accumulated factory currency |
settlements | list[Settlement] | Settlements in this region |
FactoryMoney
Factory currency accumulated in a region.
Attributes
| Name | Type | Description |
|---|---|---|
current | int | Currency waiting to be collected |
max | int | Storage cap |
Settlement
A single settlement's production state.
Attributes
| Name | Type | Description |
|---|---|---|
id | str | Settlement identifier |
name | str | Settlement name |
level | int | Settlement level |
exp_to_level_up | int | Experience needed for the next level |
current_exp | int | Experience accumulated at this level |
max_money | int | Currency storage cap |
remaining_money | int | Currency still to be produced |
char_icon | str | None | Icon of the assigned character. Required field — must be present, may be null |
last_ticked | datetime | None | Last production tick. Required field — must be present, may be null |
Monument
Returned by get_monument(). These models are the one group that uses camelCase JSON aliases with populate_by_name=True — construct them with either the Python name or the alias, but read them with the Python name. To serialize back to the upstream shape, use .model_dump(by_alias=True).
IndieHardData
Root object returned by get_monument().
Attributes
| Name | Type | Description |
|---|---|---|
indie_hard | IndieHard | JSON alias: indieHard |
IndieHard
Container for every Monument group.
Attributes
| Name | Type | Description |
|---|---|---|
indie_hard_groups | list[IndieHardGroup] | JSON alias: indieHardGroups |
IndieHardGroup
One Monument activity with its dungeons and achievement.
Attributes
| Name | Type | Description |
|---|---|---|
id | str | Group identifier |
name | str | Group name |
pic | str | Group banner image URL |
dungeon_groups | list[DungeonGroup] | JSON alias: dungeonGroups |
activity_start_ts | str | Activity start timestamp. JSON alias: activityStartTs |
activity_end_ts | str | Activity end timestamp. JSON alias: activityEndTs |
activity_name | str | Activity name. JSON alias: activityName |
achieve | Achievement | Achievement earned for this group |
is_in_activity | bool | Whether the activity is currently running. JSON alias: isInActivity |
DungeonGroup
Normal and hard variants of the same dungeon.
Attributes
Dungeon
A single Monument dungeon and the player's best clear.
Attributes
| Name | Type | Description |
|---|---|---|
id | str | Dungeon identifier |
name | str | Dungeon name |
is_pass | bool | Whether the player has cleared it. JSON alias: isPass |
best_record | BestRecord | None | Best clear, None if never cleared. Required field — must be present, may be null. JSON alias: bestRecord |
desc | str | Dungeon description |
feature | str | Special modifier text |
enemies | list[Enemy] | Enemies in this dungeon |
recommend_level | int | Recommended level. JSON alias: recommendLevel |
Enemy
An enemy appearing in a Monument dungeon.
Attributes
| Name | Type | Description |
|---|---|---|
id | str | Enemy identifier |
name | str | Enemy name |
desc | str | Enemy description |
level | int | Enemy level |
image_url | str | Enemy image URL. JSON alias: imageUrl |
ability | str | Enemy ability text |
BestRecord
The player's best clear of a dungeon, including the team used.
Attributes
| Name | Type | Description |
|---|---|---|
chars | list[IndieHardCharacter] | Team used for the clear |
ts | str | Clear time |
pass_ts | str | Timestamp of the clear. JSON alias: passTs |
IndieHardCharacter
A character as recorded in a Monument clear. A trimmed shape — not interchangeable with Character or CharacterData.
Attributes
| Name | Type | Description |
|---|---|---|
char_id | str | Character identifier. JSON alias: charId |
level | int | Level at the time of the clear |
potential_level | int | Potential level. JSON alias: potentialLevel |
avatar_url | str | Avatar image URL. JSON alias: avatarUrl |
evolve_phase | int | Ascension phase. JSON alias: evolvePhase |
property | KeyValue | Element or profession as a key/value pair |
rarity | KeyValue | Rarity as a key/value pair, not an int |
Achievement
The player's state on a Monument achievement.
Attributes
| Name | Type | Description |
|---|---|---|
achievement_data | AchievementData | Static definition. JSON alias: achievementData |
level | int | Reached level, selects which icon applies |
is_plated | bool | Whether the plated variant is earned. JSON alias: isPlated |
obtain_ts | str | Timestamp earned. JSON alias: obtainTs |
AchievementData
Static definition of an achievement, including one icon per reforge tier.
Attributes
| Name | Type | Description |
|---|---|---|
id | str | Achievement identifier |
name | str | Achievement name |
init_icon | str | Tier 1 icon URL. JSON alias: initIcon |
reforge2_icon | str | Tier 2 icon URL. JSON alias: reforge2Icon |
reforge3_icon | str | Tier 3 icon URL. JSON alias: reforge3Icon |
plated_icon | str | Plated icon URL. JSON alias: platedIcon |
cate_name | str | Category display name. JSON alias: cateName |
can_certify | bool | Whether the achievement can be certified. JSON alias: canCertify |
cate | str | Category identifier |
init_level | int | Starting level. JSON alias: initLevel |
KeyValue
A generic label pair — the raw key plus its display value. Used for a Monument character's property and rarity.
Attributes
| Name | Type | Description |
|---|---|---|
key | str | Raw key |
value | str | Display value |
IndieHardBaseModel
Base class every Monument model inherits from. Has no fields; it exists only to set model_config = ConfigDict(populate_by_name=True), which lets those models be built from either the camelCase JSON alias or the snake_case Python name.
Factory
FactoryPlans
Blueprint page returned by get_factory_blueprints().
Attributes
| Name | Type | Description |
|---|---|---|
blueprints | list[Blueprint] | Blueprints in the requested start–end slice |
total | int | Total blueprints matching the filters, before pagination — use it to page through results |
Blueprint
A shared factory blueprint.
Attributes
| Name | Type | Description |
|---|---|---|
id | str | Blueprint identifier |
name | str | Blueprint name |
description | str | Short description. Empty string if the blueprint has none |
code | str | In-game import code. Empty string if the blueprint has none |
screenshot_url | str | Thumbnail URL. Empty string if the blueprint has none |
region | str | In-game region the blueprint targets |
output_items | list[OutputItems] | What the blueprint produces and how fast |
OutputItems
One item a blueprint produces. The class name is plural but each instance describes a single item.
Attributes
| Name | Type | Description |
|---|---|---|
id | str | Item identifier |
name | str | Item slug, e.g. "xiranite". The same value accepted by the item filter. "unknown" if unresolved |
per_minute | int | Production rate per minute, rounded to the nearest integer |
icon_url | str | Item icon URL |
Examples
Basic Usage
import asyncio
from endfield import Endfield
async def main():
client = Endfield()
# Fetch player profile (public data)
showcase = await client.get_showcase(uid="123456789")
print(f"Player: {showcase.profile.name}")
print(f"Adventure Level: {showcase.profile.adventure_level}")
# Close session
await client.close()
asyncio.run(main())
Context Manager
import asyncio
from endfield import Endfield
async def main():
# Use as async context manager
async with Endfield() as client:
showcase = await client.get_showcase(uid="123456789")
print(f"Characters: {len(showcase.characters)}")
# Session auto-closes on exit
asyncio.run(main())
Fetch Authenticated Data
import asyncio
from endfield import Endfield
async def main():
async with Endfield() as client:
token = "your_token_here"
# Verify token and get the Skport account
user = await client.verify_user(token)
if user:
print(f"Verified: {user.skport_name} (UID: {user.uid})")
# Fetch game stats — every field is a model, so use attribute access
stats = await client.get_game_stats(token)
if stats:
print(f"Sanity: {stats.sanity_point.current}/{stats.sanity_point.max}")
print(f"Battle pass: Lv. {stats.battle_pass.current_level}")
for region in stats.regions.all:
print(f"{region.region_name}: factory Lv. {region.factory_level}")
# get_all_characters returns AllCharacters, not a list
roster = await client.get_all_characters(token)
if roster:
print(f"{roster.total} characters owned")
for char in roster.characters:
# note: the field is spelled `proffesion`
print(f"- {char.name} (Lv. {char.level}, {char.proffesion})")
asyncio.run(main())
Reading a Character Build
import asyncio
from endfield import Endfield
async def main():
async with Endfield() as client:
char = await client.get_character_showcase(uid="123456789", index=0)
print(f"{char.name} — Lv. {char.level} {char.element} {char.profession}")
# Final stats, already computed
print(f" HP {char.stats.hp} ATK {char.stats.atk} DEF {char.stats.defense}")
print(f" Crit {char.stats.crit_rate}% / {char.stats.crit_dmg}%")
# Display-ready form: name + icon + value, None stats omitted
for stat in char.detailed_stats.all:
marker = " (main)" if stat.main_attri else ""
print(f" {stat.name}: {stat.value}{marker}")
if char.weapon:
w = char.weapon
print(f"Weapon: {w.name} Lv. {w.level} R{w.refine_lv} (ATK {w.base_atk})")
for skill in w.skills:
# these five fields are scalars OR lists depending on the skill
if isinstance(skill.prop_id, list):
pairs = zip(skill.prop_name, skill.value)
else:
pairs = [(skill.prop_name, skill.value)]
for prop_name, value in pairs:
print(f" Lv.{skill.current_lvl} {prop_name}: {value}")
# Set bonus is None unless 3+ relics share a suit_id
if char.suit_sets and char.suit_sets.is_active:
print(f"Set: {char.suit_sets.pieces_equipped}pc active")
for prop in char.suit_sets.active_bonus.propmap or []:
print(f" {prop.prop_name}: {prop.value}")
asyncio.run(main())
Monument Progress
import asyncio
from endfield import Endfield
async def main():
async with Endfield() as client:
data = await client.get_monument(token="your_token_here")
if not data:
return
# camelCase in the JSON, snake_case on the model
for group in data.indie_hard.indie_hard_groups:
print(f"{group.name} — {group.activity_name}")
for pair in group.dungeon_groups:
for dungeon in (pair.normal_dungeon, pair.hard_dungeon):
status = "cleared" if dungeon.is_pass else "not cleared"
print(f" {dungeon.name} (Lv. {dungeon.recommend_level}): {status}")
# best_record is None if never cleared
if dungeon.best_record:
team = ", ".join(c.char_id for c in dungeon.best_record.chars)
print(f" best: {dungeon.best_record.ts} with {team}")
asyncio.run(main())
Factory Blueprints
import asyncio
from endfield import Endfield
async def main():
async with Endfield() as client:
# Get factory blueprints
plans = await client.get_factory_blueprints(
region="Both",
item="all",
start=0,
end=10
)
print(f"Total blueprints: {plans.total}")
for blueprint in plans.blueprints:
print(f"- {blueprint.name} ({blueprint.region})")
for output in blueprint.output_items:
print(f" → {output.name}: {output.per_minute}/min")
asyncio.run(main())