Search methods... ⌘K
Python SDK

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.

sessionOptional[aiohttp.ClientSession]
debugbool — Enable debug logging. Default: False
timeoutint — Timeout in seconds. Default: 5
proxy_poolOptional[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

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.

asyncrequires token

async verify_user(token: str) User | None

Verify an authentication token and retrieve the associated Skport account information.

Parameters

tokenstr — Authentication token

Returns

resultUser | None
asyncrequires uid

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

uidint | str — User ID (UID)

Returns

showcaseShowcaseData
asyncrequires uid

async get_character_showcase(uid: int | str, index: int = 0) CharacterData

Retrieve character showcase data for a specific user ID and character index.

Parameters

uidint | str — User ID (UID)
indexint — Character index. Default: 0

Returns

characterCharacterData

Raises

CharacterNotFoundErrorerrorindex is negative or beyond the number of showcased characters
asyncrequires uid

async get_profile(uid: int | str) PlayerProfile

Retrieve only the player profile data for a specific user ID.

Parameters

uidint | str — User ID (UID)

Returns

profilePlayerProfile
syncoffline

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_dataCharacterData — Character to compute; requires stats to be populated

Returns

statsComputedStatsWithDetails — Wrapper around all: list[StatDetail]
asyncrequires token

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

tokenstr — Authentication token
serverint — Server ID. Default: 3

Returns

statsGameStats | None
asyncrequires token

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

tokenstr — Authentication token
char_idstr — Character hashed ID (use get_all_characters)
genderLiteral["1", "2"] — Endministrator gender used to pick splash art and icons: "1" male, "2" female. Only affects the main character. Default: "1"

Returns

characterCharacterData
asyncrequires token

async get_all_characters(token: str) AllCharacters | None

Fetch all characters from the authenticated user's roster.

Parameters

tokenstr — Authentication token

Returns

resultAllCharacters | None
asyncrequires token

async perform_daily_sign(token: str) → str

Perform daily sign-in using an authentication token.

Parameters

tokenstr — Authentication token

Returns

messagestr — Sign-in result message
asyncrequires token

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

tokenstr — Authentication token

Returns

monumentIndieHardData | None
asyncoffline

async check_for_updates() → Any

Check for available asset updates.

asyncoffline

async update_assets() → None

Download and apply asset updates.

asyncoffline

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

regionLiteral["Americas/Europe", "Asia", "Both"] — Default: "Both"
itemLiteral["all"] | items — Output-item slug to filter by (e.g. "xiranite", "heavy-xiranite"), or "all". Default: "all"
startint — Pagination start index, 0-based. Default: 0
endint — Pagination end index, exclusive. Default: 10

Returns


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

models.basic.showcase

ShowcaseData

Root object returned by get_showcase().

Attributes

NameTypeDescription
profilePlayerProfilePlayer profile and statistics
characterslist[CharacterData]Showcased characters, each with stats and detailed_stats already populated
models.basic.profile

PlayerProfile

Player profile information. Returned on its own by get_profile(), and as ShowcaseData.profile.

Attributes

NameTypeDescription
uidstrPlayer UID
namestrPlayer name
short_idstrShort identifier, the friend code shown in-game
signaturestrPlayer signature/bio
avatar_urlstrAvatar image URL. Empty string if the avatar could not be resolved
bg_urlstrBusiness-card background URL
frame_urlstr | NoneAvatar frame URL. Default: None
adventure_levelintAdventure level
world_levelintWorld level
char_countintTotal characters owned
weapon_countintTotal weapons owned
doc_countintTotal documents collected
domain_progresslist[DomainProgress]Per-domain development levels
medalsMedalsDisplayed achievement medals
characterslist[ProfileCharacter]Business-card display characters, in display order
ttlint | NoneCache time-to-live in seconds. Default: None
models.basic.profile

ProfileCharacter

Lightweight character entry shown on a player's business card. For the full build, use CharacterData from ShowcaseData.characters.

Attributes

NameTypeDescription
template_idintNumeric character template ID
str_idstrString identifier, e.g. "chr_0030_zhuangfy"
namestrResolved character name, or "unknown"
levelintCurrent level
potential_levelintPotential level
rarityintRarity tier
elementstrElemental affinity
professionstrClass/profession type
splash_urlstrSplash art URL
round_icon_urlstrRound icon URL
models.basic.profile

DomainProgress

Development level for a single domain.

Attributes

NameTypeDescription
domain_idstrDomain identifier
levelintDevelopment level
namestrResolved domain name. Default: "unknown"
models.basic.profile

Medals

Wrapper around the player's displayed medals.

Attributes

NameTypeDescription
medalslist[Medal]Medals the player has chosen to display
models.basic.profile

Medal

A single achievement medal at the level the player has reached.

Attributes

NameTypeDescription
indexintDisplay slot on the business card. 0 if the medal is not in the display list
namestrMedal name, or "unknown"
descriptionstrUnlock condition text for the reached level
icon_urlstrIcon URL for the reached level

Character

models.basic.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

NameTypeDescription
template_idintNumeric character template ID. For the Endministrator this is the gender-specific display ID (22 male / 29 female), not the raw 38
str_idstrString identifier, e.g. "chr_0030_zhuangfy"
namestrCharacter name
rarityintRarity tier
elementstrElemental affinity
professionstrClass/profession type
weapon_typestrWeapon type the character can equip
levelintCurrent level
potential_levelintPotential level, drives talents.potential_attributes
splash_urlstrSplash art URL
bg_urlstrCharacter background art URL
round_icon_urlstrRound icon URL
main_attributeCharAttrPrimary scaling attribute
sub_attributeCharAttrSecondary scaling attribute
base_atkBaseAttrBase attack at the current level (attribute ID "2")
base_hpBaseAttrBase HP at the current level (attribute ID "1")
base_attributelist[BaseAttr]Remaining level-scaled base attributes. Default: []
weaponWeaponData | NoneEquipped weapon. Default: None
equipslist[EquipData]Equipped relics. Default: []
suit_setsSuitSet | NoneActive relic set bonus. None unless at least 3 relics share a suit_id. Default: None
skillsSkillMetaSkill loadout and levels
talentsTalentInfo | NoneTalent tree state. Default: None
statsComputedStats | NoneFinal stats after weapon, relics and talents. Default: None
detailed_statsComputedStatsWithDetails | NoneDisplay-ready form of stats. Default: None
models.basic.character

CharAttr

Identifies a character's main or sub scaling attribute. Carries no value — the value lives in ComputedStats.

Attributes

NameTypeDescription
attri_idstrAttribute ID
attri_namestrInternal attribute name, or "unknown"
urlstrAttribute icon URL. Note the field is url, not icon_url
models.basic.character

BaseAttr

A base attribute already scaled to the character's current level.

Attributes

NameTypeDescription
attri_idstrAttribute ID
attri_namestrInternal attribute name, e.g. "Atk_base"
urlstrAttribute icon URL
valueint | floatValue at the current level
is_floatboolTrue when value is a ratio rather than a flat number. Default: False
models.basic.character

SkillMeta

A character's skill loadout. The four ID fields name which entry in skills fills each slot.

Attributes

NameTypeDescription
normal_skillstrBattle skill ID
ultimate_skillstrUltimate skill ID
combo_skillstrCombo skill ID
disp_normal_atk_skillstrDisplayed normal-attack skill ID
skillslist[SkillInfo]Every skill with its level. Skills missing from the asset map are skipped
models.basic.character

SkillInfo

A single skill and its level state.

Attributes

NameTypeDescription
skill_idstrSkill identifier
icon_urlstrSkill icon URL
elementstrDamage element of the skill, or "unknown"
levelintCurrent skill level
max_levelintMaximum reachable level
enhanced_levelintEnhancement tier applied on top of level
models.basic.character

TalentInfo

Unlocked state of a character's talent tree.

Attributes

NameTypeDescription
latest_break_nodestrMost recently unlocked breakthrough node
attr_nodesAttrNodeAggregate of every unlocked attribute node, as a single object rather than a list
passive_nodeslist[TalentPassiveNode]Unlocked passive skill nodes
factory_nodeslist[TalentFactoryNode]Unlocked factory skill nodes
potential_attributeslist[PotentialAttributes]Bonuses granted by potential. Empty when potential_level is 0. Default: []
models.basic.character

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

NameTypeDescription
attri_idstrAttribute ID, or "0" if it could not be resolved
attri_namestrInternal attribute name, or "unknown"
formulastrHow the value applies. Default: "BaseAddition"
icon_urlstrAttribute icon URL
valueslist[int]Per-node contributions, in unlock order
total_valueintSum of values
levelintNumber of unlocked attribute nodes, i.e. len(values)
models.basic.character

TalentPassiveNode

An unlocked passive node in the talent tree.

Attributes

NameTypeDescription
node_idstrNode identifier
icon_urlstrNode icon URL
levelintNode tier, 1–3
indexintPosition within the talent tree
is_maxboolTrue when level >= 2. Default: False
typeintNode type code
models.basic.character

TalentFactoryNode

An unlocked factory node in the talent tree. Same shape as TalentPassiveNode, kept separate so the two node kinds stay distinguishable.

Attributes

NameTypeDescription
node_idstrNode identifier
icon_urlstrNode icon URL
levelintNode tier
indexintPosition within the talent tree
is_maxboolTrue when level >= 2. Default: False
typeintNode type code
models.basic.character

PotentialAttributes

One potential tier's worth of stat bonuses. Only tiers at or below the character's potential_level are included.

Attributes

NameTypeDescription
required_potential_levelintPotential level that unlocks this tier
attributeslist[PoteAtrri]Bonuses granted at this tier
models.basic.character

PoteAtrri

A single stat bonus from potential. The class name is spelled PoteAtrri in the source.

Attributes

NameTypeDescription
attri_idstrAttribute ID
attri_namestrInternal attribute name, or "unknown"
icon_urlstrAttribute icon URL
valueint | floatBonus amount
is_floatboolTrue when value is a ratio. Default: False
formulastrHow the bonus applies, or "unknown"

Stats

models.basic.character

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

NameTypeDescription
strintStrength
agiintAgility
wisdintIntellect
willintWill
hpintHP
atkintAttack
defenseintDefense
crit_ratefloatCritical Rate, percent. Default: 5.0
crit_dmgfloatCritical DMG, percent. Default: 50.0
arts_intensityfloatArts Intensity
healing_received_bonusfloatTreatment Received Bonus. Default: 0.0
ultimate_gain_efficiencyfloatUltimate Gain Efficiency. Default: 100.0
healing_bonusfloat | NoneTreatment Bonus. Default: None
normal_atk_dmg_bonusfloat | NoneBasic Attack DMG Bonus. Default: None
normal_skill_dmg_bonusfloat | NoneBattle Skill DMG Bonus. Default: None
combo_skill_dmg_bonusfloat | NoneCombo Skill DMG Bonus. Default: None
ult_skill_dmg_bonusfloat | NoneUltimate DMG Bonus. Default: None
physical_dmg_bonusfloat | NonePhysical DMG Bonus. Default: None
fire_dmg_bonusfloat | NoneHeat DMG Bonus. Default: None
pulse_dmg_bonusfloat | NoneElectric DMG Bonus. Default: None
cryst_dmg_bonusfloat | NoneCryo DMG Bonus. Default: None
natural_dmg_bonusfloat | NoneNature DMG Bonus. Default: None
ether_dmg_bonusfloat | NoneEther DMG Bonus. Default: None
infliction_enhancefloat | NoneArts Intensity from infliction sources. Default: None
models.basic.character

ComputedStatsWithDetails

Display-ready wrapper around ComputedStats, returned by get_detailed_stats().

Attributes

NameTypeDescription
alllist[StatDetail]One entry per non-None stat
models.basic.character

StatDetail

A single stat with everything needed to render it.

Attributes

NameTypeDescription
valueint | float | NoneStat value
icon_urlstrAttribute icon URL
stat_idstrAttribute ID, or "unknown"
namestrDisplay name, e.g. "Critical Rate", "Heat DMG Bonus"
main_attriboolTrue if this is the character's main attribute. Default: False
sub_attriboolTrue if this is the character's sub attribute. Default: False

Weapon

models.basic.weapon

WeaponData

Equipped weapon, found at CharacterData.weapon.

Attributes

NameTypeDescription
weapon_idstrWeapon template ID as a string
namestrWeapon name
rarityintRarity tier
weapon_typestrWeapon category, or "unknown"
levelintCurrent level
refine_lvintRefinement level; raises skill level bounds when above 0
breakthrough_lvintBreakthrough level; sets the base skill level bounds
base_atkfloatBase attack at the current level, rounded to 3 decimals
skill_levelslist[int]Convenience copy of each entry's current_lvl, in the same order as skills
icon_urlstrWeapon icon URL
skillslist[WeaponSkill]Weapon passives with resolved values
main_statMainStatPrimary stat line, always base attack
gemGem | NoneAttached gem, or None. Required field — must be present, may be null
models.basic.weapon

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

NameTypeDescription
skill_idstrSkill identifier
tag_idstrEffect tag identifier
prop_idstr | list[str]Affected property ID(s)
base_lvlintLower level bound from breakthrough plus refinement
max_lvlintUpper level bound from breakthrough plus refinement
current_lvlintEffective level, base_lvl plus gem cost, clamped to max_lvl
formulastr | list[str]How the value applies
prop_namestr | list[str]Internal property name(s)
icon_urlstr | list[str]Attribute icon URL(s)
valuefloat | list[float]Value(s) at current_lvl
models.basic.weapon

MainStat

A weapon's primary stat line. Every field except value is a constant default, since the main stat is always base attack.

Attributes

NameTypeDescription
valueintBase attack at the weapon's current level
prop_idstrDefault: "2"
prop_namestrDefault: "Atk_base"
formulastrDefault: "BaseAddition"
icon_urlstrDefault: "https://enka.network/ui/ef/attributeicon/Atk.png"
models.basic.weapon

Gem

A gem socketed into a weapon. Gem terms raise the effective level of the weapon's skills.

Attributes

NameTypeDescription
rarityintRarity tier, parsed from the gem's icon filename. Falls back to 3
namestrName of the last applied term. Empty string if the gem has no terms
inner_icon_urlstrTerm tag icon URL. Empty string if unresolved
cover_icon_urlstrGem cover icon URL. Empty string if unresolved

Equipment

models.basic.equipment

EquipData

A single equipped relic. Relics sharing a suit_id form a set; 3 or more activate the SuitSet bonus.

Attributes

NameTypeDescription
slot_idintEquipment slot
template_idintRelic template ID
rarityintRarity tier. Falls back to 5
suit_idstrSuit set identifier
icon_urlstrRelic icon URL
attr_modifierslist[AttrModifier]Main and sub stats. Empty if the relic has no modifiers in the asset data
models.basic.equipment

AttrModifier

One stat line on a relic.

Attributes

NameTypeDescription
indexintPosition in the relic's modifier array
attr_typeintAttribute ID as an integer
attr_namestrInternal attribute name, or "unknown"
formulastrOne of "BaseAddition", "BaseMultiplier", "BaseFinalMultiplier", or "unknown"
enhance_levelint1-based enhancement level of this line
valuefloatValue at enhance_level, rounded to 3 decimals
iconstrAttribute icon URL. Note the field is icon, not icon_url
models.basic.equipment

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

NameTypeDescription
suit_idstrSuit set identifier
namestr | NoneSet name hash. Default: None
icon_urlstrSet icon URL
pieces_equippedintNumber of pieces from this set that are equipped
is_activeboolWhether the set bonus is active
active_bonusSuitSetEffect | NoneBonus effect, populated only when is_active. Default: None
models.basic.equipment

SuitSetEffect

The effect granted by an active relic set.

Attributes

NameTypeDescription
tagidstr | NoneEffect tag identifier. All lowercase, not tag_id. Default: None
propmaplist[PropMap] | NoneStat changes, scaled to the number of pieces equipped. Default: None
models.basic.equipment

PropMap

One stat change contributed by a set bonus.

Attributes

NameTypeDescription
prop_idstrProperty ID
prop_namestrInternal property name, or "unknown"
valuefloatValue for the current piece count
formulastrHow the value applies, or "unknown"

Auth

models.auth.user

User

Skport account information returned by verify_user().

Attributes

NameTypeDescription
uidintIn-game UID
skport_idintSkport account ID
skport_namestrSkport account name
server_idintHome server ID
credstr | NoneSession credential derived from the token. Default: None
sign_tokenstr | NoneToken used for request signing. Default: None
sk_rolestr | NoneSkport role identifier. Default: None
models.auth.allc

AllCharacters

Roster returned by get_all_characters(). This is a wrapper, not a list — iterate result.characters.

Attributes

NameTypeDescription
characterslist[Character]Every character the account owns
totalintTotal character count. Default: 0
models.auth.allc

Character

A roster entry. Pass char_id to get_game_character() to fetch the full CharacterData build.

Attributes

NameTypeDescription
char_idstrHashed character identifier
namestrCharacter name
levelintCurrent level
potential_levelintPotential level
evolve_phaseintAscension phase
rarityintRarity tier
square_iconstrSquare avatar icon URL
proffesionstrClass/profession type, uppercase. The field is spelled proffesion — two f's, one s. It does not match ProfileCharacter.profession or CharacterData.profession
elementstrElemental affinity, first letter uppercase
rect_iconstrRectangular portrait icon URL
splash_iconstrFull splash art URL
owned_atintUnix timestamp of when the character was obtained

Game Stats

models.auth.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

NameTypeDescription
regionsRegionsFactory and settlement state per region
sanity_pointSanityPointStamina and recovery time
battle_passBattlePassBattle pass progress
daily_pointsDailyPointsDaily activity points
weekly_pointsWeeklyPointsWeekly challenge points
models.auth.game_stats

SanityPoint

Stamina state.

Attributes

NameTypeDescription
currentintCurrent sanity
maxintMaximum sanity
full_recover_atdatetime | NoneWhen sanity refills completely. Required field — must be present, may be null
models.auth.game_stats

BattlePass

Battle pass progress.

Attributes

NameTypeDescription
max_levelintHighest reachable level this season
current_levelintCurrent level
models.auth.game_stats

DailyPoints

Daily activity points.

Attributes

NameTypeDescription
currentintPoints earned today
maxintDaily maximum
models.auth.game_stats

WeeklyPoints

Weekly challenge points. Note the field names differ from DailyPoints.

Attributes

NameTypeDescription
scoreintPoints earned this week
totalintWeekly maximum
models.auth.game_stats

Regions

Wrapper around the account's regions.

Attributes

NameTypeDescription
alllist[Region]Every region the account has unlocked. Reached as stats.regions.all
models.auth.game_stats

Region

Factory and settlement state for one region.

Attributes

NameTypeDescription
region_idstrRegion identifier
region_namestrRegion display name
factory_levelintFactory level in this region
factory_moneyFactoryMoneyAccumulated factory currency
settlementslist[Settlement]Settlements in this region
models.auth.game_stats

FactoryMoney

Factory currency accumulated in a region.

Attributes

NameTypeDescription
currentintCurrency waiting to be collected
maxintStorage cap
models.auth.game_stats

Settlement

A single settlement's production state.

Attributes

NameTypeDescription
idstrSettlement identifier
namestrSettlement name
levelintSettlement level
exp_to_level_upintExperience needed for the next level
current_expintExperience accumulated at this level
max_moneyintCurrency storage cap
remaining_moneyintCurrency still to be produced
char_iconstr | NoneIcon of the assigned character. Required field — must be present, may be null
last_tickeddatetime | NoneLast 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).

models.auth.indie_hard

IndieHardData

Root object returned by get_monument().

Attributes

NameTypeDescription
indie_hardIndieHardJSON alias: indieHard
models.auth.indie_hard

IndieHard

Container for every Monument group.

Attributes

NameTypeDescription
indie_hard_groupslist[IndieHardGroup]JSON alias: indieHardGroups
models.auth.indie_hard

IndieHardGroup

One Monument activity with its dungeons and achievement.

Attributes

NameTypeDescription
idstrGroup identifier
namestrGroup name
picstrGroup banner image URL
dungeon_groupslist[DungeonGroup]JSON alias: dungeonGroups
activity_start_tsstrActivity start timestamp. JSON alias: activityStartTs
activity_end_tsstrActivity end timestamp. JSON alias: activityEndTs
activity_namestrActivity name. JSON alias: activityName
achieveAchievementAchievement earned for this group
is_in_activityboolWhether the activity is currently running. JSON alias: isInActivity
models.auth.indie_hard

DungeonGroup

Normal and hard variants of the same dungeon.

Attributes

NameTypeDescription
normal_dungeonDungeonJSON alias: normalDungeon
hard_dungeonDungeonJSON alias: hardDungeon
models.auth.indie_hard

Dungeon

A single Monument dungeon and the player's best clear.

Attributes

NameTypeDescription
idstrDungeon identifier
namestrDungeon name
is_passboolWhether the player has cleared it. JSON alias: isPass
best_recordBestRecord | NoneBest clear, None if never cleared. Required field — must be present, may be null. JSON alias: bestRecord
descstrDungeon description
featurestrSpecial modifier text
enemieslist[Enemy]Enemies in this dungeon
recommend_levelintRecommended level. JSON alias: recommendLevel
models.auth.indie_hard

Enemy

An enemy appearing in a Monument dungeon.

Attributes

NameTypeDescription
idstrEnemy identifier
namestrEnemy name
descstrEnemy description
levelintEnemy level
image_urlstrEnemy image URL. JSON alias: imageUrl
abilitystrEnemy ability text
models.auth.indie_hard

BestRecord

The player's best clear of a dungeon, including the team used.

Attributes

NameTypeDescription
charslist[IndieHardCharacter]Team used for the clear
tsstrClear time
pass_tsstrTimestamp of the clear. JSON alias: passTs
models.auth.indie_hard

IndieHardCharacter

A character as recorded in a Monument clear. A trimmed shape — not interchangeable with Character or CharacterData.

Attributes

NameTypeDescription
char_idstrCharacter identifier. JSON alias: charId
levelintLevel at the time of the clear
potential_levelintPotential level. JSON alias: potentialLevel
avatar_urlstrAvatar image URL. JSON alias: avatarUrl
evolve_phaseintAscension phase. JSON alias: evolvePhase
propertyKeyValueElement or profession as a key/value pair
rarityKeyValueRarity as a key/value pair, not an int
models.auth.indie_hard

Achievement

The player's state on a Monument achievement.

Attributes

NameTypeDescription
achievement_dataAchievementDataStatic definition. JSON alias: achievementData
levelintReached level, selects which icon applies
is_platedboolWhether the plated variant is earned. JSON alias: isPlated
obtain_tsstrTimestamp earned. JSON alias: obtainTs
models.auth.indie_hard

AchievementData

Static definition of an achievement, including one icon per reforge tier.

Attributes

NameTypeDescription
idstrAchievement identifier
namestrAchievement name
init_iconstrTier 1 icon URL. JSON alias: initIcon
reforge2_iconstrTier 2 icon URL. JSON alias: reforge2Icon
reforge3_iconstrTier 3 icon URL. JSON alias: reforge3Icon
plated_iconstrPlated icon URL. JSON alias: platedIcon
cate_namestrCategory display name. JSON alias: cateName
can_certifyboolWhether the achievement can be certified. JSON alias: canCertify
catestrCategory identifier
init_levelintStarting level. JSON alias: initLevel
models.auth.indie_hard

KeyValue

A generic label pair — the raw key plus its display value. Used for a Monument character's property and rarity.

Attributes

NameTypeDescription
keystrRaw key
valuestrDisplay value
models.auth.indie_hard

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

models.factory.blueprint

FactoryPlans

Blueprint page returned by get_factory_blueprints().

Attributes

NameTypeDescription
blueprintslist[Blueprint]Blueprints in the requested startend slice
totalintTotal blueprints matching the filters, before pagination — use it to page through results
models.factory.blueprint

Blueprint

A shared factory blueprint.

Attributes

NameTypeDescription
idstrBlueprint identifier
namestrBlueprint name
descriptionstrShort description. Empty string if the blueprint has none
codestrIn-game import code. Empty string if the blueprint has none
screenshot_urlstrThumbnail URL. Empty string if the blueprint has none
regionstrIn-game region the blueprint targets
output_itemslist[OutputItems]What the blueprint produces and how fast
models.factory.blueprint

OutputItems

One item a blueprint produces. The class name is plural but each instance describes a single item.

Attributes

NameTypeDescription
idstrItem identifier
namestrItem slug, e.g. "xiranite". The same value accepted by the item filter. "unknown" if unresolved
per_minuteintProduction rate per minute, rounded to the nearest integer
icon_urlstrItem icon URL

Examples

Basic Usage

python
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

python
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

python
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

python
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

python
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

python
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())