Skip to content

Player cards held by a wallet

GET
/api/players/{address}
curl --request GET \
--url https://foxleague.ai/api/players/example

Answers the player cards a wallet holds with their game data, sorted by shirt number. A card listed on the marketplace sits with the marketplace contract and is left out. condition includes the recovery since it was last stored. The answer for a wallet can be up to 30 seconds old.

Asked by the wallet’s own session, the cards are read from the chain; when the chain cannot be read, the list comes from FoxLeague’s own records. Any other caller (no session, another player) gets the list from FoxLeague’s own records.

Who: anyone.

Refusals: none.

An address that is not a wallet address answers HTTP 400 with an empty body. If the list cannot be read on our side, the answer is HTTP 500 with an empty body.

address
required
string

The wallet address (erd1...).

Success or a refusal: read success (the refusals are in the description).

Media type application/json
object
code

A machine-readable reason next to error, set only where the caller must act differently. tx_pending: the payment was not refused but could not be verified yet; keep the transaction hash and confirm again with the same hash, never pay twice.

string | null
data

The answer. Present when success is true.

Array<object>

One player card with its game data.

object
accuracy
required

Current accuracy value, capped by rarity (Common 30, Uncommon 55, Rare 75, Epic 90, Legendary 100).

integer format: int32
accuracy_synced
required

The accuracy value as last synced to chain.

integer format: int32
accuracy_xp
required

Training XP toward the next accuracy point.

integer format: int32
acquired_at

When the current owner got the card; null when unknown.

string | null format: date-time
assists
required

Career assists.

integer format: int32
catches
required

Career catches.

integer format: int32
competitive_matches
required

Appearances in competitive matches (paid tournament seats and 1v1 challenges against a real opponent; ranked matches never count). They count toward the match gate of the card’s rarity (rarity_match_gate in /api/config).

integer format: int32
condition
required

Condition from 0 to 100, the recovery up to condition_updated_at included.

integer format: int32
condition_updated_at
required

The moment the recovery in condition was earned up to (RFC 3339). Recovery counts from here: the recovery after it is not in condition yet.

string format: date-time
control
required

Current control value, capped by rarity (Common 30, Uncommon 55, Rare 75, Epic 90, Legendary 100).

integer format: int32
control_synced
required

The control value as last synced to chain.

integer format: int32
control_xp
required

Training XP toward the next control point.

integer format: int32
country
required

Country index, 0 to 43.

integer format: int32
created_at
required

When FoxLeague first recorded the card (RFC 3339). This is not the mint time.

string format: date-time
defense
required

Current defense value, capped by rarity (Common 30, Uncommon 55, Rare 75, Epic 90, Legendary 100).

integer format: int32
defense_synced
required

The defense value as last synced to chain.

integer format: int32
defense_xp
required

Training XP toward the next defense point.

integer format: int32
experience
required

The card’s total XP.

integer format: int32
experience_synced
required

Total XP as last synced to chain.

integer format: int32
fused_at

When the card was made by fusion (RFC 3339); null for a card not made by fusion.

string | null format: date-time
fusion_match_credit
required

Matches bought for this card with the match waiver. They count toward the match gate of its rarity (gate in rarity_match_gate of /api/config), never toward the matches it must really play (floor).

integer format: int32
fusion_ready_at

When the card can be fused again (RFC 3339); null when it can be fused now.

string | null format: date-time
goals
required

Career goals.

integer format: int32
id
required

FoxLeague’s record number of the card. Use nft_nonce to name a card.

integer format: int32
level
required

The card’s level.

integer format: int32
level_synced
required

The level as last synced to chain.

integer format: int32
listed_for_sale
required

true while the card is listed on the marketplace.

boolean
matches_played
required

Every match the card has played.

integer format: int32
minted_at

When the card was minted (RFC 3339). It sets the card’s age. null when unknown.

string | null format: date-time
name
required

The player’s name.

string
nft_nonce
required

The card’s NFT nonce.

integer format: int64
owner_address
required

The wallet that holds the card. While the card is listed, the seller.

string
passes
required

Career passes.

integer format: int32
portrait_uri

Address of the portrait image; null when none.

string | null
position
required

GK, DEF, MID or FWD.

string
power
required

Current power value, capped by rarity (Common 30, Uncommon 55, Rare 75, Epic 90, Legendary 100).

integer format: int32
power_synced
required

The power value as last synced to chain.

integer format: int32
power_xp
required

Training XP toward the next power point.

integer format: int32
rarity
required

Common, Uncommon, Rare, Epic or Legendary.

string
sale_price

Asking price in whole FOXSY while listed; null otherwise.

integer | null format: int64
shirt_number
required

Shirt number.

integer format: int32
shots_on_target
required

Career shots on target.

integer format: int32
speed
required

Current speed value, capped by rarity (Common 30, Uncommon 55, Rare 75, Epic 90, Legendary 100).

integer format: int32
speed_synced
required

The speed value as last synced to chain.

integer format: int32
speed_xp
required

Training XP toward the next speed point.

integer format: int32
stamina
required

Current stamina value, capped by rarity (Common 30, Uncommon 55, Rare 75, Epic 90, Legendary 100).

integer format: int32
stamina_synced
required

The stamina value as last synced to chain.

integer format: int32
stamina_xp
required

Training XP toward the next stamina point.

integer format: int32
stats_dirty
required

true when the card has changes not yet synced to chain.

boolean
synced_stats
required

Always true.

boolean
tackles
required

Career tackles.

integer format: int32
transfer_cooldown_hours

Length in hours of the card’s transfer lock, counted from transferred_at; null means transfer_cooldown_hours from /api/config applies. For a rarity_gate lock it is the length now: the hours of every match bought for the card since it moved are already taken off.

integer | null format: int32
transfer_lock_kind
One of:

The kind of a card’s transfer lock: rarity_gate (the card was sent before it reached its gate; Reduce Cooldown does not apply, each match bought for the card shortens the lock down to a floor; a listed card already sits at its floor), standard (the usual lock; Reduce Cooldown applies) or per_card (a lock set before the rarity rules; Reduce Cooldown applies).

string
Allowed values: rarity_gate standard per_card
transferred_at

When the card last arrived by a direct transfer from another wallet (RFC 3339); its transfer lock counts from here. A card made by fusion from cards still under a transfer lock carries on the lock that ends last. null when neither.

string | null format: date-time
vision
required

Current vision value, capped by rarity (Common 30, Uncommon 55, Rare 75, Epic 90, Legendary 100).

integer format: int32
vision_synced
required

The vision value as last synced to chain.

integer format: int32
vision_xp
required

Training XP toward the next vision point.

integer format: int32
error

Why the request was refused, in plain words. Present when success is false.

string | null
success
required

true when the request did what it asked. false is a refusal: read error.

boolean
Example
{
"data": [
{
"accuracy": 22,
"accuracy_synced": 22,
"accuracy_xp": 0,
"acquired_at": "2026-09-16T08:03:51.004912Z",
"assists": 1,
"catches": 118,
"competitive_matches": 17,
"condition": 100,
"condition_updated_at": "2026-09-30T19:42:07.318204Z",
"control": 24,
"control_synced": 24,
"control_xp": 40,
"country": 23,
"created_at": "2026-09-16T08:03:51.004912Z",
"defense": 30,
"defense_synced": 30,
"defense_xp": 0,
"experience": 3350,
"experience_synced": 3350,
"fused_at": null,
"fusion_match_credit": 0,
"fusion_ready_at": null,
"goals": 0,
"id": 5822,
"level": 4,
"level_synced": 4,
"listed_for_sale": false,
"matches_played": 39,
"minted_at": "2026-09-15T14:27:12Z",
"name": "Lars Holm",
"nft_nonce": 1301,
"owner_address": "erd15feryxhrdz9m6y09mr8wrerwzgj6f8ntxvhxyrdlm5aahn0t09nl4ujy86",
"passes": 402,
"portrait_uri": "https://ipfs.io/ipfs/bafybeiczsscdsbs7ffqz55asqdf3smv6klcw3gofszvwlyarci47bgf354/1301.png",
"position": "GK",
"power": 25,
"power_synced": 25,
"power_xp": 120,
"rarity": "Common",
"sale_price": null,
"shirt_number": 1,
"shots_on_target": 0,
"speed": 27,
"speed_synced": 27,
"speed_xp": 300,
"stamina": 29,
"stamina_synced": 29,
"stamina_xp": 80,
"stats_dirty": false,
"synced_stats": true,
"tackles": 3,
"transfer_cooldown_hours": null,
"transfer_lock_kind": null,
"transferred_at": null,
"vision": 28,
"vision_synced": 28,
"vision_xp": 560
},
{
"accuracy": 57,
"accuracy_synced": 57,
"accuracy_xp": 640,
"acquired_at": "2026-09-16T08:03:51.004912Z",
"assists": 14,
"catches": 0,
"competitive_matches": 21,
"condition": 86,
"condition_updated_at": "2026-09-30T19:42:07.318204Z",
"control": 66,
"control_synced": 65,
"control_xp": 1530,
"country": 0,
"created_at": "2026-09-16T08:03:51.004912Z",
"defense": 44,
"defense_synced": 44,
"defense_xp": 220,
"experience": 7420,
"experience_synced": 7210,
"fused_at": null,
"fusion_match_credit": 0,
"fusion_ready_at": null,
"goals": 9,
"id": 5821,
"level": 6,
"level_synced": 6,
"listed_for_sale": false,
"matches_played": 47,
"minted_at": "2026-09-15T14:27:12Z",
"name": "Renan Silva",
"nft_nonce": 1234,
"owner_address": "erd15feryxhrdz9m6y09mr8wrerwzgj6f8ntxvhxyrdlm5aahn0t09nl4ujy86",
"passes": 1288,
"portrait_uri": "https://ipfs.io/ipfs/bafybeiczsscdsbs7ffqz55asqdf3smv6klcw3gofszvwlyarci47bgf354/1234.png",
"position": "MID",
"power": 49,
"power_synced": 49,
"power_xp": 0,
"rarity": "Rare",
"sale_price": null,
"shirt_number": 8,
"shots_on_target": 33,
"speed": 61,
"speed_synced": 60,
"speed_xp": 1180,
"stamina": 58,
"stamina_synced": 58,
"stamina_xp": 310,
"stats_dirty": true,
"synced_stats": true,
"tackles": 61,
"transfer_cooldown_hours": null,
"transfer_lock_kind": null,
"transferred_at": null,
"vision": 63,
"vision_synced": 63,
"vision_xp": 905
}
],
"success": true
}

address is not a wallet address (erd1...). The body is empty.

No valid session. The body is plain text: Missing Authorization header, Invalid Authorization format, Invalid session token or Session expired or invalid. Sign in again.

Media type text/plain
string
Example
Session expired or invalid

The cards could not be read on our side. The body is empty.