clashy

package module
v0.1.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2026 License: MIT Imports: 19 Imported by: 0

README

clashy.go

Easy-to-use Go SDK for the Clash of Clans API.

Key Features

  • Go-native client built around context.Context
  • Broad coverage of the official Clash of Clans API
  • Developer-site email/password login, or direct token login
  • Built-in rate limiting, caching, and static game-data helpers

Getting Started

Installing

Go 1.25 or higher is required

go get github.com/clashkinginc/clashy.go

To use the latest development version:

go get github.com/clashkinginc/clashy.go@main

Quick Example

This is the basic usage of the library. This example logs in, fetches a player, searches for clans, and loads the current war for a clan.

package main

import (
	"context"
	"errors"
	"fmt"
	"log"

	clashy "github.com/clashkinginc/clashy.go"
)

func main() {
	ctx := context.Background()

	client, err := clashy.NewClient(clashy.DefaultClientConfig())
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = client.Close() }()

	if err := client.Login(ctx, "email", "password"); err != nil {
		var invalid *clashy.InvalidCredentials
		if errors.As(err, &invalid) {
			log.Fatal("invalid developer credentials")
		}
		log.Fatal(err)
	}

	player, err := client.GetPlayer(ctx, "#TAG")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s has %d trophies\n", player.Name, player.Trophies)

	clans, err := client.SearchClans(ctx, clashy.SearchClansRequest{
		Name:  "best clan ever",
		Limit: 5,
	})
	if err != nil {
		log.Fatal(err)
	}

	for _, clan := range clans {
		fmt.Printf("%s (%s) has %d members\n", clan.Name, clan.Tag, clan.MemberCount)
	}

	war, err := client.GetCurrentWar(ctx, "#CLANTAG")
	if err != nil {
		var privateWarLog *clashy.PrivateWarLog
		if errors.As(err, &privateWarLog) {
			fmt.Println("uh oh, they have a private war log")
			return
		}
		log.Fatal(err)
	}

	fmt.Printf("%s is currently in %s state\n", war.ClanTag, war.State)
}

If you already have API tokens, you can skip developer-site login:

package main

import (
	"context"
	"log"

	clashy "github.com/clashkinginc/clashy.go"
)

func main() {
	ctx := context.Background()

	client, err := clashy.NewClient(clashy.DefaultClientConfig())
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = client.Close() }()

	if err := client.LoginWithTokens(ctx, "your-api-token"); err != nil {
		log.Fatal(err)
	}
}

Other Features

The client also includes helpers for:

  • locations, rankings, leagues, labels, and gold pass endpoints
  • battle logs, raid logs, war logs, and CWL data
  • player token verification
  • static game-data lookups such as troops, spells, heroes, pets, equipment, and translations

Contributing

Contributions are welcome. If you find a bug or want to add functionality, open an issue or submit a pull request.

To run the test suite:

go test ./...

Disclaimer

This content is not affiliated with, endorsed, sponsored, or specifically approved by Supercell, and Supercell is not responsible for it. For more information, see Supercell's Fan Content Policy.

Documentation

Overview

Package clashy provides a Go SDK for the Clash of Clans API and compatible ClashKing proxy-style APIs.

The package is organized around the resource shapes exposed by the official API: clans, players, wars, Clan War League groups, locations, rankings, leagues, labels, gold pass seasons, raid weekends, and player battle logs. Client methods accept context.Context values for cancellation and deadlines, return typed Go models, and map common API failures onto typed errors that can be inspected with errors.As.

A Client can authenticate with existing API tokens through LoginWithTokens or with developer-site credentials through Login. The underlying HTTP client rotates tokens, applies a simple concurrency limit, decodes compressed responses, honors cache headers for GET requests, and preserves retry metadata on response models that embed responseMeta.

The package also embeds ClashKing static game data. Static helpers resolve troops, spells, heroes, pets, hero equipment, translations, and army-link payloads without forcing callers to learn the static JSON layout.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// TroopBaseID is the base static-data ID offset for troops in army links.
	TroopBaseID = 4000000
	// SpellBaseID is the base static-data ID offset for spells in army links.
	SpellBaseID = 26000000
	// HeroBaseID is the base static-data ID offset for heroes in army links.
	HeroBaseID = 28000000
	// PetBaseID is the base static-data ID offset for pets in army links.
	PetBaseID = 73000000
	// EquipmentBaseID is the base static-data ID offset for hero equipment in army links.
	EquipmentBaseID = 90000000
	// ElixirTroopOrder lists regular home-village elixir troops in UI order.
	ElixirTroopOrder = []string{
		"Barbarian",
		"Archer",
		"Goblin",
		"Giant",
		"Wall Breaker",
		"Balloon",
		"Wizard",
		"Healer",
		"Dragon",
		"P.E.K.K.A",
		"Baby Dragon",
		"Miner",
		"Yeti",
		"Electro Dragon",
		"Dragon Rider",
		"Electro Titan",
		"Root Rider",
		"Thrower",
		"Meteor Golem",
	}
	// DarkElixirTroopOrder lists regular home-village dark elixir troops in UI order.
	DarkElixirTroopOrder = []string{
		"Minion",
		"Hog Rider",
		"Valkyrie",
		"Golem",
		"Witch",
		"Lava Hound",
		"Bowler",
		"Ice Golem",
		"Headhunter",
		"Apprentice Warden",
		"Ruin Witch",
		"Druid",
		"Furnace",
	}
	// HomeTroopOrder lists regular home-village troops in UI order.
	HomeTroopOrder = append(append([]string{}, ElixirTroopOrder...), DarkElixirTroopOrder...)
	// SiegeMachineOrder lists siege machines in UI order.
	SiegeMachineOrder = []string{
		"Wall Wrecker",
		"Battle Blimp",
		"Stone Slammer",
		"Siege Barracks",
		"Log Launcher",
		"Flame Flinger",
		"Battle Drill",
		"Troop Launcher",
		"Sky Wagon",
	}
	// SuperTroopOrder lists super troops in UI order.
	SuperTroopOrder = []string{
		"Super Barbarian",
		"Super Archer",
		"Super Wall Breaker",
		"Super Giant",
		"Sneaky Goblin",
		"Super Miner",
		"Rocket Balloon",
		"Inferno Dragon",
		"Super Valkyrie",
		"Super Witch",
		"Ice Hound",
		"Super Bowler",
		"Super Dragon",
		"Super Wizard",
		"Super Minion",
		"Super Hog Rider",
		"Super Yeti",
	}
	// HomeTroopOrderWithSieges lists regular home-village troops followed by siege machines.
	HomeTroopOrderWithSieges = append(append([]string{}, HomeTroopOrder...), SiegeMachineOrder...)
	// SeasonalTroopOrder lists temporary seasonal troops in static-data order.
	SeasonalTroopOrder = []string{
		"Ice Wizard",
		"Battle Ram",
		"Royal Ghost",
		"Pumpkin Barbarian",
		"Giant Skeleton",
		"Skeleton Barrel",
		"M.E.C.H.A",
		"Party Wizard",
		"Ram Rider",
		"Barcher",
		"Witch Golem",
		"Hog Wizard",
		"Lavaloon",
		"C.O.O.K.I.E",
		"Firecracker",
		"Azure Dragon",
		"Barbarian Kicker",
		"Giant Thrower",
		"Broom Witch",
		"Ice Minion",
		"Debt Collector",
		"Snake Barrel",
		"Giant Giant",
		"K.A.N.E",
		"The Disarmer",
		"YEETer",
		"Meteor Golem",
		"Elephant Rider",
	}
	// BuilderTroopOrder lists Builder Base troops in UI order.
	BuilderTroopOrder = []string{
		"Raged Barbarian",
		"Sneaky Archer",
		"Beta Minion",
		"Boxer Giant",
		"Bomber",
		"Power P.E.K.K.A",
		"Cannon Cart",
		"Drop Ship",
		"Baby Dragon",
		"Night Witch",
		"Hog Glider",
		"Electrofire Wizard",
	}
	// ElixirSpellOrder lists regular elixir spells in UI order.
	ElixirSpellOrder = []string{
		"Lightning Spell",
		"Healing Spell",
		"Rage Spell",
		"Jump Spell",
		"Freeze Spell",
		"Clone Spell",
		"Invisibility Spell",
		"Recall Spell",
		"Revive Spell",
		"Totem Spell",
	}
	// DarkElixirSpellOrder lists regular dark elixir spells in UI order.
	DarkElixirSpellOrder = []string{
		"Poison Spell",
		"Earthquake Spell",
		"Haste Spell",
		"Skeleton Spell",
		"Bat Spell",
		"Overgrowth Spell",
		"Ice Block Spell",
		"Angry Spell",
	}
	// SeasonalSpellOrder lists temporary seasonal spells in static-data order.
	SeasonalSpellOrder = []string{
		"Santa's Surprise",
		"Bag of Frostmites",
	}
	// SpellOrder lists regular spells in UI order.
	SpellOrder = append(append([]string{}, ElixirSpellOrder...), DarkElixirSpellOrder...)
	// HomeBaseHeroOrder lists home-village heroes in unlock order.
	HomeBaseHeroOrder = []string{
		"Barbarian King",
		"Archer Queen",
		"Minion Prince",
		"Grand Warden",
		"Royal Champion",
		"Dragon Duke",
	}
	// BuilderBaseHeroOrder lists Builder Base heroes in unlock order.
	BuilderBaseHeroOrder = []string{
		"Battle Machine",
		"Battle Copter",
	}
	// HeroOrder lists all heroes in home-village then Builder Base order.
	HeroOrder = append(append([]string{}, HomeBaseHeroOrder...), BuilderBaseHeroOrder...)
	// PetOrder lists hero pets in unlock order.
	PetOrder = []string{
		"L.A.S.S.I",
		"Mighty Yak",
		"Electro Owl",
		"Unicorn",
		"Phoenix",
		"Poison Lizard",
		"Diggy",
		"Frosty",
		"Spirit Fox",
		"Angry Jelly",
		"Sneezy",
		"Greedy Raven",
	}
	// EquipmentOrder lists hero equipment in static-data order.
	EquipmentOrder = []string{
		"Barbarian Puppet",
		"Rage Vial",
		"Archer Puppet",
		"Invisibility Vial",
		"Eternal Tome",
		"Life Gem",
		"Seeking Shield",
		"Royal Gem",
		"Earthquake Boots",
		"Hog Rider Puppet",
		"Giant Gauntlet",
		"Vampstache",
		"Haste Vial",
		"Rocket Spear",
		"Spiky Ball",
		"Frozen Arrow",
		"Monolith Arrow",
		"Giant Arrow",
		"Heroic Torch",
		"Healer Puppet",
		"Fireball",
		"Rage Gem",
		"Snake Bracelet",
		"Healing Tome",
		"Dark Crown",
		"Magic Mirror",
		"Electro Boots",
		"Lavaloon Puppet",
		"Henchmen Puppet",
		"Dark Orb",
		"Metal Pants",
		"Noble Iron",
		"Action Figure",
		"Meteor Staff",
		"Frost Flake",
		"Stick Horse",
		"Fire Heart",
		"Rocket Backpack",
		"Stun Blaster",
		"Flame Blower",
		"Electro Fangs",
		"Revenge Deck",
	}
	// HVBuildingOrder lists home-village buildings in static-data order.
	HVBuildingOrder = []string{
		"Army Camp",
		"Town Hall",
		"Elixir Collector",
		"Elixir Storage",
		"Gold Mine",
		"Gold Storage",
		"Barracks",
		"Laboratory",
		"Cannon",
		"Archer Tower",
		"Wall",
		"Wizard Tower",
		"Air Defense",
		"Mortar",
		"Clan Castle",
		"Builder's Hut",
		"Hidden Tesla",
		"Spell Factory",
		"X-Bow",
		"Dark Elixir Drill",
		"Dark Elixir Storage",
		"Dark Barracks",
		"Inferno Tower",
		"Air Sweeper",
		"Dark Spell Factory",
		"Eagle Artillery",
		"Bomb Tower",
		"Workshop",
		"B.O.B's Hut",
		"Scattershot",
		"Pet House",
		"Blacksmith",
		"Hero Hall",
		"Spell Tower",
		"Monolith",
		"Multi-Gear Tower",
		"Sour Elixir Cauldron",
		"Multi-Archer Tower",
		"Ricochet Cannon",
		"Revenge Tower",
		"Firespitter",
		"Helper Hut",
		"Crafting Station",
		"Super Wizard Tower",
	}
	// AchievementOrder lists achievements in village and UI-priority order.
	AchievementOrder = []string{
		"Keep Your Account Safe!",
		"Bigger & Better",
		"Discover New Troops",
		"Bigger Coffers",
		"Gold Grab",
		"Elixir Escapade",
		"Heroic Heist",
		"Well Seasoned",
		"Nice and Tidy",
		"Empire Builder",
		"Clan War Wealth",
		"Friend in Need",
		"Sharing is caring",
		"Siege Sharer",
		"War Hero",
		"War League Legend",
		"Games Champion",
		"Unbreakable",
		"Sweet Victory!",
		"Conqueror",
		"League All-Star",
		"League Follower",
		"League Enthusiast",
		"League Superfan",
		"League Fanatic",
		"League Master",
		"Humiliator",
		"Not So Easy This Time",
		"Union Buster",
		"Bust This!",
		"Wall Buster",
		"Mortar Mauler",
		"X-Bow Exterminator",
		"Firefighter",
		"Anti-Artillery",
		"Shattered and Scattered",
		"Counterspell",
		"Monolith Masher",
		"Multi-Archer Tower Terminator",
		"Ricochet Cannon Crusher",
		"Firespitter Finisher",
		"Multi-Gear Tower Trampler",
		"Crafter’s Nightmare",
		"Get those Goblins!",
		"Supercharger",
		"Crafting Connoisseur",
		"Get those other Goblins!",
		"Get even more Goblins!",
		"Dragon Slayer",
		"Ungrateful Child",
		"Superb Work",
		"Master Engineering",
		"Hidden Treasures",
		"High Gear",
		"Next Generation Model",
		"Un-Build It",
		"Champion Builder",
		"Aggressive Capitalism",
		"Most Valuable Clanmate",
	}
)
View Source
var ErrInvalidLimit = errors.New("clashy: requests per second must be greater than zero")

ErrInvalidLimit is returned when a limiter is created or used without a positive requests-per-second limit.

Functions

func CorrectTag

func CorrectTag(tag string) string

CorrectTag normalizes a Clash tag by trimming whitespace, uppercasing, replacing O with 0, removing invalid characters, and ensuring a leading #.

Example
package main

import (
	"fmt"

	clashy "github.com/clashkinginc/clashy.go"
)

func main() {
	fmt.Println(clashy.CorrectTag(" o0q l "))

}
Output:
#00QL

func FromTimestamp

func FromTimestamp(raw string) (time.Time, error)

FromTimestamp parses a Clash API timestamp in 20060102T150405.000Z format.

func GenLegendDate added in v0.1.4

func GenLegendDate(timestamp time.Time) string

GenLegendDate returns the legend-league day identifier for timestamp.

Legend days roll over at 05:00 UTC, so timestamps before that hour map to the previous calendar date.

func GenSeasonDate added in v0.1.4

func GenSeasonDate(timestamp time.Time) string

GenSeasonDate returns the trophy season identifier for timestamp.

func GetClanGamesEnd

func GetClanGamesEnd(timestamp time.Time) time.Time

GetClanGamesEnd returns the Clan Games end time for the month containing timestamp, rolling forward after that month's Clan Games end.

func GetClanGamesStart

func GetClanGamesStart(timestamp time.Time) time.Time

GetClanGamesStart returns the Clan Games start time for the month containing timestamp, rolling forward after that month's Clan Games end.

func GetRaidWeekendEnd

func GetRaidWeekendEnd(timestamp time.Time) time.Time

GetRaidWeekendEnd returns the end time for the raid weekend containing timestamp.

func GetRaidWeekendStart

func GetRaidWeekendStart(timestamp time.Time) time.Time

GetRaidWeekendStart returns the start time for the raid weekend containing timestamp.

func GetSeasonEnd added in v0.1.4

func GetSeasonEnd(timestamp time.Time) time.Time

GetSeasonEnd returns the end time of the trophy season containing timestamp.

func GetSeasonID

func GetSeasonID() string

GetSeasonID returns the current trophy season identifier in YYYY-MM form.

func GetSeasonStart added in v0.1.4

func GetSeasonStart(timestamp time.Time) time.Time

GetSeasonStart returns the start time of the trophy season containing timestamp.

func WithoutRateLimit

func WithoutRateLimit(ctx context.Context) context.Context

WithoutRateLimit returns a child context that bypasses the client's request limiter.

Use this for trusted internal calls where the caller is already controlling concurrency. It does not disable token rotation, caching, deadlines, or HTTP transport behavior.

Types

type AccountData

type AccountData struct {
	// Raw contains the original account-link payload.
	Raw map[string]any
}

AccountData is a thin wrapper around arbitrary account-link data.

func ParseAccountData

func ParseAccountData(data map[string]any) AccountData

ParseAccountData wraps account-link data without mutating it.

type Achievement

type Achievement struct {
	// Name is the achievement display name.
	Name string `json:"name"`
	// Stars is the number of achievement stars earned.
	Stars int `json:"stars"`
	// Value is the current progress value.
	Value int `json:"value"`
	// Target is the value needed to complete the achievement.
	Target int `json:"target"`
	// Info describes the achievement goal.
	Info string `json:"info"`
	// CompletionInfo describes the completed achievement state.
	CompletionInfo string `json:"completionInfo"`
	// Village identifies the village or game area for the achievement.
	Village string `json:"village"`
}

Achievement describes one player achievement and its current progress.

type ArmyRecipe

type ArmyRecipe struct {
	// Link is the original link or raw army payload passed by the caller.
	Link string
	// HeroesLoadout contains heroes, pets, and equipment from the link.
	HeroesLoadout []HeroLoadout
	// Troops contains home-army troops from the link.
	Troops []TroopCount
	// Spells contains home-army spells from the link.
	Spells []SpellCount
	// ClanCastleTroops contains requested Clan Castle troops.
	ClanCastleTroops []TroopCount
	// ClanCastleSpells contains requested Clan Castle spells.
	ClanCastleSpells []SpellCount
}

ArmyRecipe is the normalized representation of a Clash army link.

func ParseArmyRecipe

func ParseArmyRecipe(static *StaticData, link string) ArmyRecipe

ParseArmyRecipe parses a full Clash army link or raw army payload into a structured recipe using embedded static data for names and villages.

Example
package main

import (
	"fmt"
	"log"

	clashy "github.com/clashkinginc/clashy.go"
)

func main() {
	staticData, err := clashy.LoadStaticData()
	if err != nil {
		log.Fatal(err)
	}

	recipe := clashy.ParseArmyRecipe(staticData, "u10x0-2x5s3x2")
	fmt.Println(len(recipe.Troops))
	fmt.Println(len(recipe.Spells))

}
Output:
2
1

type Badge

type Badge struct {
	// Small is the small badge image URL.
	Small string `json:"small"`
	// Medium is the medium badge image URL.
	Medium string `json:"medium"`
	// Large is the large badge image URL.
	Large string `json:"large"`
}

Badge contains the common small, medium, and large image URLs for clan badges.

func (Badge) URL

func (b Badge) URL() string

URL returns the preferred badge URL, choosing medium, then large, then small.

type BattleLogEntry

type BattleLogEntry struct {
	// BattleType describes the game mode for the battle.
	BattleType BattleType `json:"battleType,omitempty"`
	// Attack reports whether the entry is an attack made by the requested
	// player. False entries are defenses.
	Attack bool `json:"attack,omitempty"`
	// ArmyShareCode is the in-game army share payload when available.
	ArmyShareCode string `json:"armyShareCode,omitempty"`
	// OpponentPlayerTag is the opponent's player tag.
	OpponentPlayerTag string `json:"opponentPlayerTag,omitempty"`
	// OpponentName is the opponent's display name.
	OpponentName string `json:"opponentName,omitempty"`
	// OpponentTownHallLevel is the opponent's Town Hall level.
	OpponentTownHallLevel int `json:"opponentTownHallLevel,omitempty"`
	// Stars is the number of stars earned by the attacker.
	Stars int `json:"stars,omitempty"`
	// DestructionPercentage is the destruction percentage earned by the attacker.
	DestructionPercentage int `json:"destructionPercentage,omitempty"`
	// LootedResources contains resources actually looted.
	LootedResources []Resource `json:"lootedResources,omitempty"`
	// ExtraLootedResources contains bonus resources awarded by the battle.
	ExtraLootedResources []Resource `json:"extraLootedResources,omitempty"`
	// AvailableLoot contains resources that were available before the battle.
	AvailableLoot []Resource `json:"availableLoot,omitempty"`
	// Duration is the battle duration in seconds.
	Duration int `json:"battleTime,omitempty"`
	// Timestamp is the API timestamp for when the battle happened.
	Timestamp string `json:"battleTimestamp,omitempty"`
	// contains filtered or unexported fields
}

BattleLogEntry is one player battle log entry.

func (BattleLogEntry) RetryAfter

func (m BattleLogEntry) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type BattleModifier added in v0.1.13

type BattleModifier string

BattleModifier describes the modifier applied to a war battle.

const (
	// BattleModifierNone means the war has no battle modifier.
	BattleModifierNone BattleModifier = "none"
	// BattleModifierHardMode is the esports hard mode modifier.
	BattleModifierHardMode BattleModifier = "hardMode"
	// BattleModifierMinusOne is the Legend I battle modifier.
	BattleModifierMinusOne BattleModifier = "minusOne"
	// BattleModifierMinusTwo is the Legend II battle modifier.
	BattleModifierMinusTwo BattleModifier = "minusTwo"
	// BattleModifierMinusThree is the Legend III battle modifier.
	BattleModifierMinusThree BattleModifier = "minusThree"
)

func (BattleModifier) InGameName added in v0.1.13

func (m BattleModifier) InGameName() string

InGameName returns a client-facing display name for the battle modifier.

type BattleType added in v0.1.13

type BattleType string

BattleType describes the game mode for a player battle log entry.

const (
	// BattleTypeHomeVillage is a home-village battle log entry.
	BattleTypeHomeVillage BattleType = "HOME_VILLAGE"
	// BattleTypeRanked is a ranked battle log entry.
	BattleTypeRanked BattleType = "RANKED"
	// BattleTypeLegend is a Legend League battle log entry.
	BattleTypeLegend BattleType = "LEGEND"
)

type CapitalDistrict

type CapitalDistrict struct {
	// ID is the district identifier.
	ID int `json:"id"`
	// Name is the district display name.
	Name string `json:"name"`
	// DistrictHallLevel is the district hall level.
	DistrictHallLevel int `json:"districtHallLevel"`
	// DestructionPercent is the destruction percentage in raid contexts.
	DestructionPercent float64 `json:"destructionPercent"`
	// AttackCount is the number of attacks used against the district.
	AttackCount int `json:"attackCount"`
	// Looted is the total capital gold looted from the district.
	Looted int `json:"totalLooted"`
}

CapitalDistrict describes a clan capital district from clan and raid data.

type ChatLanguage

type ChatLanguage struct {
	// ID is the language identifier.
	ID int `json:"id"`
	// Name is the language display name.
	Name string `json:"name"`
	// LanguageCode is the language code returned by the API.
	LanguageCode string `json:"languageCode"`
}

ChatLanguage describes the preferred language configured for a clan.

type Clan

type Clan struct {
	// Tag is the clan tag.
	Tag string `json:"tag,omitempty"`
	// Name is the clan display name.
	Name string `json:"name,omitempty"`
	// Type describes whether the clan is open, closed, or invite-only.
	Type ClanType `json:"type,omitempty"`
	// Description is the public clan description.
	Description string `json:"description,omitempty"`
	// FamilyFriendly reports whether the clan is marked family friendly.
	FamilyFriendly bool `json:"isFamilyFriendly,omitempty"`
	// Level is the clan level.
	Level int `json:"clanLevel,omitempty"`
	// Points is the clan's home village trophy score.
	Points int `json:"clanPoints,omitempty"`
	// BuilderBasePoints is the clan's Builder Base trophy score.
	BuilderBasePoints int `json:"clanBuilderBasePoints,omitempty"`
	// CapitalPoints is the clan's Clan Capital score.
	CapitalPoints int `json:"clanCapitalPoints,omitempty"`
	// RequiredTrophies is the home village trophy requirement to join.
	RequiredTrophies int `json:"requiredTrophies,omitempty"`
	// WarFrequency is the clan's declared war frequency.
	WarFrequency string `json:"warFrequency,omitempty"`
	// WarWinStreak is the current classic-war win streak.
	WarWinStreak int `json:"warWinStreak,omitempty"`
	// WarWins is the number of classic-war wins.
	WarWins int `json:"warWins,omitempty"`
	// WarTies is the number of classic-war ties when the API includes it.
	WarTies int `json:"warTies,omitempty"`
	// WarLosses is the number of classic-war losses when the API includes it.
	WarLosses int `json:"warLosses,omitempty"`
	// PublicWarLog reports whether the clan war log is public.
	PublicWarLog bool `json:"isWarLogPublic,omitempty"`
	// MemberCount is the number of current clan members.
	MemberCount int `json:"members,omitempty"`
	// RequiredBuilderBaseTrophies is the Builder Base trophy requirement to
	// join.
	RequiredBuilderBaseTrophies int `json:"requiredBuilderBaseTrophies,omitempty"`
	// RequiredTownhall is the minimum Town Hall level required to join.
	RequiredTownhall int `json:"requiredTownhallLevel,omitempty"`
	// Location is the clan's declared location.
	Location *Location `json:"location,omitempty"`
	// Badge contains the clan badge image URLs.
	Badge Badge `json:"badgeUrls,omitempty"`
	// Labels are public labels assigned to the clan.
	Labels []Label `json:"labels,omitempty"`
	// Members is the member list embedded in full clan responses.
	Members []ClanMember `json:"memberList,omitempty"`
	// WarLeague is the clan's current Clan War League tier.
	WarLeague League `json:"warLeague,omitempty"`
	// CapitalLeague is the clan's Clan Capital league.
	CapitalLeague *League `json:"capitalLeague,omitempty"`
	// ChatLanguage is the clan's preferred chat language.
	ChatLanguage *ChatLanguage `json:"chatLanguage,omitempty"`
	// ClanCapital contains Clan Capital district information.
	ClanCapital *ClanCapital `json:"clanCapital,omitempty"`
	// contains filtered or unexported fields
}

Clan is the full clan profile returned by GetClan and search endpoints.

func (*Clan) GetMember

func (c *Clan) GetMember(tag string) *ClanMember

GetMember returns the member with the provided tag, or nil when the clan member list does not contain that tag.

func (*Clan) GetMemberBy

func (c *Clan) GetMemberBy(name string, trophies int) *ClanMember

GetMemberBy returns the first member matching the provided name and trophy filters.

Empty name and zero trophies are treated as wildcards, which is useful when a caller only has one of the two values from an external event.

func (Clan) RetryAfter

func (m Clan) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type ClanCapital

type ClanCapital struct {
	// Districts contains the visible Clan Capital districts and their hall
	// levels.
	Districts []CapitalDistrict `json:"districts,omitempty"`
}

ClanCapital describes a clan's capital districts from the clan profile.

type ClanMember

type ClanMember struct {
	// Tag is the member's player tag.
	Tag string `json:"tag,omitempty"`
	// Name is the member's player name.
	Name string `json:"name,omitempty"`
	// Role is the member's clan role.
	Role Role `json:"role,omitempty"`
	// ExpLevel is the player's experience level.
	ExpLevel int `json:"expLevel,omitempty"`
	// TownHall is the player's home village Town Hall level.
	TownHall int `json:"townHallLevel,omitempty"`
	// Trophies is the player's home village trophy count.
	Trophies int `json:"trophies,omitempty"`
	// ClanRank is the player's current position in the clan trophy ranking.
	ClanRank int `json:"clanRank,omitempty"`
	// ClanPreviousRank is the player's previous position in the clan trophy
	// ranking.
	ClanPreviousRank int `json:"previousClanRank,omitempty"`
	// Donations is the number of troops donated this season.
	Donations int `json:"donations,omitempty"`
	// Received is the number of donated troops received this season.
	Received int `json:"donationsReceived,omitempty"`
	// VersusTrophies is the legacy Builder Base trophy field used by older API
	// responses.
	VersusTrophies int `json:"versusTrophies,omitempty"`
	// BuilderBaseTrophies is the player's Builder Base trophy count.
	BuilderBaseTrophies int `json:"builderBaseTrophies,omitempty"`
	// VersusRank is the legacy Builder Base rank field used by older API
	// responses.
	VersusRank int `json:"versusRank,omitempty"`
	// BuilderBaseRank is the player's current Builder Base rank in the clan.
	BuilderBaseRank int `json:"builderBaseRank,omitempty"`
	// LeagueTier is the player's home village league.
	LeagueTier League `json:"leagueTier,omitempty"`
	// contains filtered or unexported fields
}

ClanMember describes a member entry from a clan profile or member list.

func (ClanMember) RetryAfter

func (m ClanMember) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type ClanType

type ClanType string

ClanType describes a clan's join policy.

const (
	// ClanTypeOpen means players can join directly when requirements are met.
	ClanTypeOpen ClanType = "open"
	// ClanTypeClosed means the clan is closed to new members.
	ClanTypeClosed ClanType = "closed"
	// ClanTypeInviteOnly means players must request or be invited to join.
	ClanTypeInviteOnly ClanType = "inviteOnly"
)

type ClanWar

type ClanWar struct {
	// State is the current state of the war.
	State WarState `json:"state,omitempty"`
	// TeamSize is the roster size for each side.
	TeamSize int `json:"teamSize,omitempty"`
	// PreparationStartTime is when preparation day began.
	PreparationStartTime *Timestamp `json:"preparationStartTime,omitempty"`
	// StartTime is when battle day starts.
	StartTime *Timestamp `json:"startTime,omitempty"`
	// EndTime is when the war ends.
	EndTime *Timestamp `json:"endTime,omitempty"`
	// Clan is the requested clan side for oriented responses.
	Clan *WarClan `json:"clan,omitempty"`
	// Opponent is the opposing clan side for oriented responses.
	Opponent *WarClan `json:"opponent,omitempty"`
	// BattleModifier describes event-specific modifiers when the API includes
	// one.
	BattleModifier BattleModifier `json:"battleModifier,omitempty"`
	// WarTag is the CWL war tag. It is empty for normal classic wars.
	WarTag string `json:"tag,omitempty"`
	// ClanTag is the requested clan tag associated with this response.
	ClanTag string `json:"-"`
	// LeagueGroup is the CWL group used to find this war when available.
	LeagueGroup *ClanWarLeagueGroup `json:"-"`
	// contains filtered or unexported fields
}

ClanWar is the current, historical, or league war response.

For league wars found through GetCurrentWar or GetLeagueWar, the client orients the result so Clan is the requested clan and Opponent is the opposing side, even if the API returned the requested clan under opponent.

func (*ClanWar) Attacks

func (w *ClanWar) Attacks() []WarAttack

Attacks returns all attacks made by both sides of the war.

func (*ClanWar) Member added in v0.1.13

func (w *ClanWar) Member(tag string) *ClanWarMember

Member returns the war member with tag from either side of the war.

func (*ClanWar) ResolveAttack added in v0.1.13

func (w *ClanWar) ResolveAttack(attack WarAttack) (attacker, defender *ClanWarMember)

ResolveAttack resolves an attack's tags to the matching war members.

func (ClanWar) RetryAfter

func (m ClanWar) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

func (*ClanWar) Type

func (w *ClanWar) Type() string

Type returns "cwl" when the war has a CWL war tag and "random" otherwise.

type ClanWarLeagueClan

type ClanWarLeagueClan struct {
	// Tag is the clan tag.
	Tag string `json:"tag,omitempty"`
	// Name is the clan name.
	Name string `json:"name,omitempty"`
	// Badge contains clan badge image URLs.
	Badge Badge `json:"badgeUrls,omitempty"`
	// Level is the clan level.
	Level int `json:"clanLevel,omitempty"`
	// Members is the frozen master roster registered for this CWL clan.
	Members []ClanWarLeagueClanMember `json:"members,omitempty"`
}

ClanWarLeagueClan is a clan entry inside a CWL group.

type ClanWarLeagueClanMember added in v0.1.13

type ClanWarLeagueClanMember struct {
	// Tag is the player's tag.
	Tag string `json:"tag,omitempty"`
	// Name is the player's name at registration time.
	Name string `json:"name,omitempty"`
	// TownHallLevel is the player's Town Hall level at registration time.
	TownHallLevel int `json:"townHallLevel,omitempty"`
}

ClanWarLeagueClanMember is one player in a CWL clan's master roster.

type ClanWarLeagueGroup

type ClanWarLeagueGroup struct {
	// State is the group state returned by the API.
	State string `json:"state,omitempty"`
	// Season is the CWL season identifier returned by the API.
	Season string `json:"season,omitempty"`
	// Clans contains the clans participating in the group.
	Clans []ClanWarLeagueClan `json:"clans,omitempty"`
	// Rounds contains CWL war tags grouped by round. Future rounds may contain
	// placeholder "#0" tags.
	Rounds []struct {
		WarTags []string `json:"warTags,omitempty"`
	} `json:"rounds,omitempty"`
	// contains filtered or unexported fields
}

ClanWarLeagueGroup is the current CWL group for a clan.

func (ClanWarLeagueGroup) RetryAfter

func (m ClanWarLeagueGroup) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type ClanWarLogEntry

type ClanWarLogEntry struct {
	// Result is the requested clan's result for this war.
	Result WarResult `json:"result,omitempty"`
	// EndTime is when the war ended.
	EndTime *Timestamp `json:"endTime,omitempty"`
	// TeamSize is the roster size for each side.
	TeamSize int `json:"teamSize,omitempty"`
	// Clan is the requested clan side.
	Clan *WarClan `json:"clan,omitempty"`
	// Opponent is the opposing clan side.
	Opponent *WarClan `json:"opponent,omitempty"`
	// BattleModifier describes event-specific modifiers when the API includes
	// one.
	BattleModifier BattleModifier `json:"battleModifier,omitempty"`
	// contains filtered or unexported fields
}

ClanWarLogEntry is one item from a clan's public war log.

func (ClanWarLogEntry) RetryAfter

func (m ClanWarLogEntry) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type ClanWarMember

type ClanWarMember struct {
	// Tag is the player's tag.
	Tag string `json:"tag,omitempty"`
	// Name is the player's display name at the time of the war.
	Name string `json:"name,omitempty"`
	// MapPosition is the player's position on the war map.
	MapPosition int `json:"mapPosition,omitempty"`
	// Townhall is the player's Town Hall level in the war response.
	Townhall int `json:"townhallLevel,omitempty"`
	// OpponentAttacks is the number of attacks used against this base.
	OpponentAttacks int `json:"opponentAttacks,omitempty"`
	// Attacks contains attacks made by this member.
	Attacks []WarAttack `json:"attacks,omitempty"`
	// BestOpponentAttack is the best attack received by this member.
	BestOpponentAttack *WarAttack `json:"bestOpponentAttack,omitempty"`
}

ClanWarMember is a player entry on one side of a war.

type ClashOfClansException

type ClashOfClansException struct {
	// Message is the human-readable error message.
	Message string
}

ClashOfClansException is the base package error type.

func (*ClashOfClansException) Error

func (e *ClashOfClansException) Error() string

Error implements the error interface.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the high-level Clash API client.

A Client owns its configuration and HTTP transport. It is safe to reuse a single client across request handlers as long as callers pass appropriate contexts.

func NewClient

func NewClient(cfg ClientConfig) (*Client, error)

NewClient constructs a Client from cfg. Embedded static data is parsed lazily when a static-data helper is first used.

If cfg.BaseURL is empty, DefaultClientConfig is used. BaseURL and DeveloperBaseURL are normalized by removing trailing slashes.

Example
package main

import (
	"context"
	"log"

	clashy "github.com/clashkinginc/clashy.go"
)

func main() {
	ctx := context.Background()

	client, err := clashy.NewClient(clashy.DefaultClientConfig())
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = client.Close() }()

	if err := client.LoginWithTokens(ctx, "api-token"); err != nil {
		log.Fatal(err)
	}
}

func (*Client) Close

func (c *Client) Close() error

Close releases client resources.

func (*Client) GetBattleLog

func (c *Client) GetBattleLog(ctx context.Context, playerTag string) ([]BattleLogEntry, error)

GetBattleLog fetches a player's battle log.

func (*Client) GetBuilderBaseLeague

func (c *Client) GetBuilderBaseLeague(ctx context.Context, id int) (*League, error)

GetBuilderBaseLeague fetches a Builder Base league by ID.

func (*Client) GetCapitalLeague

func (c *Client) GetCapitalLeague(ctx context.Context, id int) (*League, error)

GetCapitalLeague fetches a Clan Capital league by ID.

func (*Client) GetClan

func (c *Client) GetClan(ctx context.Context, tag string) (*Clan, error)

GetClan fetches a clan profile by tag.

func (*Client) GetClanLabels

func (c *Client) GetClanLabels(ctx context.Context, page PageOptions) ([]Label, error)

GetClanLabels fetches clan labels with optional pagination.

func (*Client) GetClanWar

func (c *Client) GetClanWar(ctx context.Context, clanTag string) (*ClanWar, error)

GetClanWar fetches the regular current-war endpoint for a clan.

This method does not fall back to CWL. Use GetCurrentWar when you want the active normal war or the relevant Clan War League war.

func (*Client) GetClanWars

func (c *Client) GetClanWars(ctx context.Context, tags []string) ([]ClanWar, error)

GetClanWars fetches the regular current war for each clan tag in order.

func (*Client) GetCurrentGoldPassSeason

func (c *Client) GetCurrentGoldPassSeason(ctx context.Context) (*GoldPassSeason, error)

GetCurrentGoldPassSeason fetches the current Gold Pass season.

func (*Client) GetCurrentWar

func (c *Client) GetCurrentWar(ctx context.Context, clanTag string, round ...WarRound) (*ClanWar, error)

GetCurrentWar returns the clan's active normal war or relevant CWL war.

The method first checks the regular current-war endpoint. If the clan is not in a regular war, or the war log is private, it loads the CWL group and returns the selected league round for the clan. Passing no round selects CurrentWar. When no current war exists, the method returns nil, nil.

func (*Client) GetCurrentWars

func (c *Client) GetCurrentWars(ctx context.Context, tags []string) ([]ClanWar, error)

GetCurrentWars fetches GetCurrentWar for each clan tag and omits clans with no current war.

func (*Client) GetEquipment

func (c *Client) GetEquipment(name string, level int) *StaticUnit

GetEquipment looks up hero equipment by name and level in embedded static data.

func (*Client) GetExtendedCWLGroupData

func (c *Client) GetExtendedCWLGroupData(name string) *ExtendedCWLGroup

GetExtendedCWLGroupData returns static medal data for a Clan War League tier by name.

func (*Client) GetHero

func (c *Client) GetHero(name string, level int) *StaticUnit

GetHero looks up a hero by name and level in embedded static data.

func (*Client) GetLeague

func (c *Client) GetLeague(ctx context.Context, id int) (*League, error)

GetLeague fetches a home-village league by ID.

func (*Client) GetLeagueGroup

func (c *Client) GetLeagueGroup(ctx context.Context, clanTag string) (*ClanWarLeagueGroup, error)

GetLeagueGroup fetches the current Clan War League group for a clan.

func (*Client) GetLeagueWar

func (c *Client) GetLeagueWar(ctx context.Context, clanTag string, round WarRound) (*ClanWar, error)

GetLeagueWar fetches the selected CWL round for a clan.

The returned war is oriented so Clan is the requested clan and Opponent is the opposing side.

func (*Client) GetLeagueWars

func (c *Client) GetLeagueWars(ctx context.Context, warTags []string) ([]ClanWar, error)

GetLeagueWars fetches CWL wars by war tag.

func (*Client) GetLocation

func (c *Client) GetLocation(ctx context.Context, locationID int) (*Location, error)

GetLocation fetches a location by numeric ID.

func (*Client) GetLocationClans

func (c *Client) GetLocationClans(ctx context.Context, locationID int, page PageOptions) ([]RankedClan, error)

GetLocationClans fetches home-village clan rankings for a numeric location ID.

func (*Client) GetLocationClansBuilderBase

func (c *Client) GetLocationClansBuilderBase(ctx context.Context, locationID int, page PageOptions) ([]RankedClan, error)

GetLocationClansBuilderBase fetches Builder Base clan rankings for a numeric location ID.

func (*Client) GetLocationClansBuilderBaseByLocationID added in v0.1.4

func (c *Client) GetLocationClansBuilderBaseByLocationID(ctx context.Context, locationID string, page PageOptions) ([]RankedClan, error)

GetLocationClansBuilderBaseByLocationID fetches Builder Base clan rankings for a location ID string.

func (*Client) GetLocationClansByLocationID added in v0.1.4

func (c *Client) GetLocationClansByLocationID(ctx context.Context, locationID string, page PageOptions) ([]RankedClan, error)

GetLocationClansByLocationID fetches home-village clan rankings for a location ID string.

func (*Client) GetLocationClansCapital

func (c *Client) GetLocationClansCapital(ctx context.Context, locationID int, page PageOptions) ([]RankedClan, error)

GetLocationClansCapital fetches Clan Capital clan rankings for a numeric location ID.

func (*Client) GetLocationClansCapitalByLocationID added in v0.1.4

func (c *Client) GetLocationClansCapitalByLocationID(ctx context.Context, locationID string, page PageOptions) ([]RankedClan, error)

GetLocationClansCapitalByLocationID fetches Clan Capital clan rankings for a location ID string.

func (*Client) GetLocationNamed

func (c *Client) GetLocationNamed(ctx context.Context, locationName string) (*Location, error)

GetLocationNamed returns the first location whose name matches locationName case-insensitively.

It returns nil, nil when no matching location is found.

func (*Client) GetLocationPlayers

func (c *Client) GetLocationPlayers(ctx context.Context, locationID int, page PageOptions) ([]RankedPlayer, error)

GetLocationPlayers fetches home-village player rankings for a numeric location ID.

func (*Client) GetLocationPlayersBuilderBase

func (c *Client) GetLocationPlayersBuilderBase(ctx context.Context, locationID int, page PageOptions) ([]RankedPlayer, error)

GetLocationPlayersBuilderBase fetches Builder Base player rankings for a numeric location ID.

func (*Client) GetLocationPlayersBuilderBaseByLocationID added in v0.1.4

func (c *Client) GetLocationPlayersBuilderBaseByLocationID(ctx context.Context, locationID string, page PageOptions) ([]RankedPlayer, error)

GetLocationPlayersBuilderBaseByLocationID fetches Builder Base player rankings for a location ID string.

func (*Client) GetLocationPlayersByLocationID added in v0.1.4

func (c *Client) GetLocationPlayersByLocationID(ctx context.Context, locationID string, page PageOptions) ([]RankedPlayer, error)

GetLocationPlayersByLocationID fetches home-village player rankings for a location ID string.

func (*Client) GetMembers

func (c *Client) GetMembers(ctx context.Context, clanTag string, page PageOptions) ([]ClanMember, error)

GetMembers fetches a clan member page by clan tag.

func (*Client) GetPet

func (c *Client) GetPet(name string, level int) *StaticUnit

GetPet looks up a pet by name and level in embedded static data.

func (*Client) GetPlayer

func (c *Client) GetPlayer(ctx context.Context, tag string) (*Player, error)

GetPlayer fetches a player profile by tag.

func (*Client) GetPlayerLabels

func (c *Client) GetPlayerLabels(ctx context.Context, page PageOptions) ([]Label, error)

GetPlayerLabels fetches player labels with optional pagination.

func (*Client) GetPlayerLeagueGroup

func (c *Client) GetPlayerLeagueGroup(ctx context.Context, playerTag, leagueGroupTag, leagueSeasonID string) (*LeagueTierGroup, error)

GetPlayerLeagueGroup fetches a ranked group and scopes it to a player.

func (*Client) GetPlayerLeagueHistory

func (c *Client) GetPlayerLeagueHistory(ctx context.Context, playerTag string) ([]LeagueHistoryEntry, error)

GetPlayerLeagueHistory fetches a player's legend league history.

func (*Client) GetRaidLog

func (c *Client) GetRaidLog(ctx context.Context, clanTag string, page PageOptions) ([]RaidLogEntry, error)

GetRaidLog fetches Clan Capital raid weekend log entries for a clan.

func (*Client) GetSeasonRankings

func (c *Client) GetSeasonRankings(ctx context.Context, leagueID int, seasonID string) ([]RankedPlayer, error)

GetSeasonRankings fetches player rankings for a league season.

func (*Client) GetSeasons

func (c *Client) GetSeasons(ctx context.Context, leagueID int) ([]string, error)

GetSeasons fetches available season IDs for a league.

Passing leagueID 0 uses the default legend league ID.

func (*Client) GetSpell

func (c *Client) GetSpell(name string, level int) *StaticUnit

GetSpell looks up a spell by name and level in embedded static data.

func (*Client) GetTranslation

func (c *Client) GetTranslation(id string) *Translation

GetTranslation returns a translation entry by static-data translation ID.

func (*Client) GetTroop

func (c *Client) GetTroop(name string, isHomeVillage bool, level int) *StaticUnit

GetTroop looks up a troop by name, village, and level in embedded static data.

func (*Client) GetWarLeague

func (c *Client) GetWarLeague(ctx context.Context, id int) (*League, error)

GetWarLeague fetches a Clan War League tier by ID.

func (*Client) GetWarLog

func (c *Client) GetWarLog(ctx context.Context, clanTag string, page PageOptions) ([]ClanWarLogEntry, error)

GetWarLog fetches public war log entries for a clan.

func (*Client) Login

func (c *Client) Login(ctx context.Context, email, password string) error

Login authenticates with developer-site email and password credentials.

The developer login flow discovers or creates API keys, stores them in the underlying HTTP client, and uses those keys for later Clash API requests.

func (*Client) LoginWithTokens

func (c *Client) LoginWithTokens(_ context.Context, tokens ...string) error

LoginWithTokens configures one or more existing Clash API tokens.

Tokens are rotated by the underlying HTTP client. The context parameter is accepted for API symmetry with Login.

func (*Client) ParseAccountData

func (c *Client) ParseAccountData(data map[string]any) AccountData

ParseAccountData wraps arbitrary account-link data without mutating it.

func (c *Client) ParseArmyLink(link string) ArmyRecipe

ParseArmyLink parses a full Clash army link or raw army payload using the client's static data.

func (*Client) SearchBuilderBaseLeagues

func (c *Client) SearchBuilderBaseLeagues(ctx context.Context, page PageOptions) ([]League, error)

SearchBuilderBaseLeagues fetches Builder Base leagues with optional pagination.

func (*Client) SearchCapitalLeagues

func (c *Client) SearchCapitalLeagues(ctx context.Context, page PageOptions) ([]League, error)

SearchCapitalLeagues fetches Clan Capital leagues with optional pagination.

func (*Client) SearchClans

func (c *Client) SearchClans(ctx context.Context, req SearchClansRequest) ([]Clan, error)

SearchClans searches clans using the provided optional filters.

func (*Client) SearchLeagues

func (c *Client) SearchLeagues(ctx context.Context, page PageOptions) ([]League, error)

SearchLeagues fetches home-village leagues with optional pagination.

func (*Client) SearchLocations

func (c *Client) SearchLocations(ctx context.Context, page PageOptions) ([]Location, error)

SearchLocations fetches API locations with optional pagination.

func (*Client) SearchWarLeagues

func (c *Client) SearchWarLeagues(ctx context.Context, page PageOptions) ([]League, error)

SearchWarLeagues fetches Clan War League tiers with optional pagination.

func (*Client) StaticData

func (c *Client) StaticData() *StaticData

StaticData returns the client's embedded static-data index.

func (*Client) VerifyPlayerToken

func (c *Client) VerifyPlayerToken(ctx context.Context, playerTag, token string) (bool, error)

VerifyPlayerToken verifies an in-game player API token.

type ClientConfig

type ClientConfig struct {
	// KeyCount is the number of developer-site API keys Login should make
	// available for token rotation.
	KeyCount int
	// KeyNames is the developer-site key name used when reusing or creating API
	// keys during Login.
	KeyNames string
	// ThrottleLimit is the maximum number of concurrent HTTP requests allowed by
	// the client. A value less than or equal to zero disables the limiter.
	ThrottleLimit int
	// Timeout is applied to the underlying http.Client.
	Timeout time.Duration
	// MaxBaseURLConns optionally caps total active and idle connections to the
	// configured API base URL.
	MaxBaseURLConns int
	// IdleConnTimeout controls how long idle HTTP connections remain reusable.
	IdleConnTimeout time.Duration
	// BaseURL is the Clash API or compatible proxy base URL, usually ending in
	// /v1 without a trailing slash.
	BaseURL string
	// DeveloperBaseURL is the developer-site base URL used only by Login.
	DeveloperBaseURL string
	// IP overrides the IP address used when Login creates developer-site API
	// keys. When empty, the IP is inferred from the temporary developer token.
	IP string
	// Realtime adds realtime=true to current-war requests that support it.
	Realtime bool
	// CacheMaxSize bounds the number of GET responses retained in memory.
	CacheMaxSize int
	// CacheMaxEntryBytes prevents unusually large responses from being retained
	// in the in-memory cache. A value less than or equal to zero disables this
	// per-entry limit.
	CacheMaxEntryBytes int
	// LookupCache allows GET requests to return fresh cached responses.
	LookupCache bool
	// UpdateCache allows successful GET responses to refresh the in-memory cache.
	UpdateCache bool
	// UserAgent is sent with Clash API or proxy requests.
	UserAgent string
	// DeveloperUserAgent is sent with developer-site login and key-management
	// requests.
	DeveloperUserAgent string
}

ClientConfig controls API endpoints, authentication behavior, request throttling, response caching, and transport behavior.

Most callers should start from DefaultClientConfig and override only the fields that differ for their service. The zero value is not the recommended production configuration because it has no API base URL or timeout.

func DefaultClientConfig

func DefaultClientConfig() ClientConfig

DefaultClientConfig returns the recommended baseline configuration for the official Clash of Clans API.

The defaults enable GET response caching, a 30 second timeout, and a conservative request throttle. Callers using a ClashKing proxy typically override BaseURL and may enable Realtime.

type Equipment

type Equipment struct {
	// Name is the equipment display name.
	Name string `json:"name"`
	// Level is the player's current level or the selected static level.
	Level int `json:"level"`
	// MaxLevel is the maximum level available for the player or in static data.
	MaxLevel int `json:"maxLevel"`
	// Village identifies the equipment's village.
	Village string `json:"village"`
	// Rarity is the equipment rarity when static data includes it.
	Rarity string `json:"rarity"`
}

Equipment is hero equipment from a player response.

func (Equipment) Static

func (e Equipment) Static(c *Client) *StaticUnit

Static returns the embedded static-data record matching this equipment's name and level.

type ExtendedCWLGroup

type ExtendedCWLGroup struct {
	// Name is the league display name.
	Name string `json:"name,omitempty"`
	// FirstPlaceMedals is the medal reward for first place.
	FirstPlaceMedals int `json:"first_place_medals,omitempty"`
	// SecondPlaceMedals is the medal reward for second place.
	SecondPlaceMedals int `json:"second_place_medals,omitempty"`
}

ExtendedCWLGroup contains static medal information for a CWL league.

type Forbidden

type Forbidden struct{ *HTTPException }

Forbidden represents a 403 response from the API.

type GatewayError

type GatewayError struct{ *HTTPException }

GatewayError represents transport failures and 5xx gateway responses.

type GoldPassSeason

type GoldPassSeason struct {
	// StartTime is when the Gold Pass season starts.
	StartTime *Timestamp `json:"startTime"`
	// EndTime is when the Gold Pass season ends.
	EndTime *Timestamp `json:"endTime"`
	// contains filtered or unexported fields
}

GoldPassSeason describes the current Gold Pass season.

func (GoldPassSeason) RetryAfter

func (m GoldPassSeason) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type HTTPClient

type HTTPClient struct {
	// contains filtered or unexported fields
}

HTTPClient performs low-level Clash API and developer-site HTTP requests.

Most callers should use Client instead. HTTPClient is exported so advanced integrations can build compatible request flows while reusing token rotation, throttling, compression handling, cache storage, and typed error mapping.

func NewHTTPClient

func NewHTTPClient(cfg ClientConfig) *HTTPClient

NewHTTPClient constructs an HTTPClient from cfg.

func (*HTTPClient) CloseIdleConnections added in v0.1.13

func (h *HTTPClient) CloseIdleConnections()

CloseIdleConnections closes idle keep-alive connections owned by this client's transport.

func (*HTTPClient) Do

func (h *HTTPClient) Do(ctx context.Context, method, fullURL string, body any, options RequestOptions) (HTTPResponse, error)

Do sends one HTTP request and returns its named result.

Non-2xx API responses return the HTTPResponse alongside the package's typed HTTP error. Successful GET responses can be read from or written to the in-memory cache depending on RequestOptions.

func (*HTTPClient) LoginDeveloper

func (h *HTTPClient) LoginDeveloper(ctx context.Context, email, password string) error

LoginDeveloper authenticates against the Clash developer site and configures API tokens for subsequent Clash API requests.

The method reuses matching keys for the configured IP and key name when possible, creating more keys until ClientConfig.KeyCount is satisfied.

func (*HTTPClient) SetTokens

func (h *HTTPClient) SetTokens(tokens ...string)

SetTokens replaces the API tokens used for Authorization headers.

Tokens are rotated one per request. Passing no tokens clears authentication.

type HTTPException

type HTTPException struct {
	// Status is the HTTP status code returned by the API. It can be zero for
	// transport failures mapped to GatewayError.
	Status int
	// Reason is the API reason string when one was provided.
	Reason string
	// Message is the API message string when one was provided.
	Message string
	// Body is the raw response body retained for debugging.
	Body []byte
}

HTTPException captures a non-successful API response.

The typed HTTP errors in this package embed HTTPException so callers can match either the specific type or inspect shared status, reason, message, and body fields.

func (*HTTPException) Error

func (e *HTTPException) Error() string

Error implements the error interface.

type HTTPResponse added in v0.1.13

type HTTPResponse struct {
	// Body is the decoded response payload.
	Body []byte
	// StatusCode is the HTTP response status.
	StatusCode int
	// RetryAfter is the remaining server-declared cache lifetime.
	RetryAfter time.Duration
}

HTTPResponse is the result of a low-level HTTP request.

type Hero

type Hero struct {
	// Name is the hero display name.
	Name string `json:"name"`
	// Level is the player's current level or the selected static level.
	Level int `json:"level"`
	// MaxLevel is the maximum level available for the player or in static data.
	MaxLevel int `json:"maxLevel"`
	// Village identifies the hero's village.
	Village string `json:"village"`
	// Equipment contains equipment currently assigned to this hero when the API
	// includes loadout data.
	Equipment []Equipment `json:"equipment"`
}

Hero is a hero from a player response.

func (Hero) Static

func (h Hero) Static(c *Client) *StaticUnit

Static returns the embedded static-data record matching this hero's name and level.

type HeroLoadout

type HeroLoadout struct {
	// Hero is the hero selected in the army link.
	Hero Hero
	// Pet is the assigned pet when the link includes one.
	Pet *Pet
	// Equipment is the selected hero equipment in link order.
	Equipment []Equipment
}

HeroLoadout is one hero, pet, and equipment grouping parsed from an army link.

type Icon

type Icon struct {
	// Small is the small icon URL.
	Small string `json:"small"`
	// Medium is the medium icon URL.
	Medium string `json:"medium"`
	// Tiny is the tiny icon URL.
	Tiny string `json:"tiny"`
}

Icon contains small icon URLs returned for leagues and labels.

type InvalidArgument

type InvalidArgument struct{ *HTTPException }

InvalidArgument represents a 400 response from the API.

type InvalidCredentials

type InvalidCredentials struct{ *HTTPException }

InvalidCredentials represents a developer-site authentication failure.

type Label

type Label struct {
	// ID is the label identifier.
	ID int `json:"id"`
	// Name is the label display name.
	Name string `json:"name"`
	// Icon contains label icon URLs.
	Icon *Icon `json:"iconUrls"`
	// contains filtered or unexported fields
}

Label is a player or clan label.

func (Label) RetryAfter

func (m Label) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type League

type League struct {
	// ID is the numeric league identifier.
	ID int `json:"id"`
	// Name is the league display name.
	Name string `json:"name"`
	// Icon contains league icon URLs when the endpoint provides them.
	Icon *Icon `json:"iconUrls"`
	// contains filtered or unexported fields
}

League is a league, war league, builder-base league, or capital league.

func (League) RetryAfter

func (m League) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type LeagueHistoryEntry

type LeagueHistoryEntry struct {
	// LeagueSeasonID is the numeric legend season identifier.
	LeagueSeasonID int `json:"leagueSeasonId,omitempty"`
	// LeagueTrophies is the player's ending legend trophy count.
	LeagueTrophies int `json:"leagueTrophies,omitempty"`
	// LeagueTierID is the league tier identifier for the season.
	LeagueTierID int `json:"leagueTierId,omitempty"`
	// Placement is the player's final placement.
	Placement int `json:"placement,omitempty"`
	// AttackWins is the number of attack wins.
	AttackWins int `json:"attackWins,omitempty"`
	// AttackLosses is the number of attack losses.
	AttackLosses int `json:"attackLosses,omitempty"`
	// AttackStars is the total stars earned on attack.
	AttackStars int `json:"attackStars,omitempty"`
	// DefenseWins is the number of defense wins.
	DefenseWins int `json:"defenseWins,omitempty"`
	// DefenseLosses is the number of defense losses.
	DefenseLosses int `json:"defenseLosses,omitempty"`
	// DefenseStars is the total stars allowed on defense.
	DefenseStars int `json:"defenseStars,omitempty"`
	// MaxBattles is the maximum battle count for the season.
	MaxBattles int `json:"maxBattles,omitempty"`
	// contains filtered or unexported fields
}

LeagueHistoryEntry is one historical legend-league season result.

func (LeagueHistoryEntry) RetryAfter

func (m LeagueHistoryEntry) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type LeagueTierGroup

type LeagueTierGroup struct {
	// Members contains the players in the legend group.
	Members []LeagueTierGroupMember `json:"members,omitempty"`
	// AttackLogs contains attack entries for the requested player.
	AttackLogs []LeagueTierGroupBattleLogEntry `json:"attackLogs,omitempty"`
	// DefenseLogs contains defense entries for the requested player.
	DefenseLogs []LeagueTierGroupBattleLogEntry `json:"defenseLogs,omitempty"`
	// contains filtered or unexported fields
}

LeagueTierGroup contains members and battle logs for a legend league group.

func (LeagueTierGroup) RetryAfter

func (m LeagueTierGroup) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type LeagueTierGroupBattleLogEntry

type LeagueTierGroupBattleLogEntry struct {
	// OpponentPlayerTag is the opponent's player tag.
	OpponentPlayerTag string `json:"opponentPlayerTag,omitempty"`
	// OpponentName is the opponent's player name.
	OpponentName string `json:"opponentName,omitempty"`
	// Stars is the number of stars earned by the attacker.
	Stars int `json:"stars,omitempty"`
	// DestructionPercentage is the destruction percentage earned by the attacker.
	DestructionPercentage int `json:"destructionPercentage,omitempty"`
	// Trophies is the trophy delta for the battle.
	Trophies int `json:"trophies,omitempty"`
	// CreationTime is the API timestamp for the battle.
	CreationTime string `json:"creationTime,omitempty"`
}

LeagueTierGroupBattleLogEntry is one attack or defense inside a legend group.

type LeagueTierGroupMember

type LeagueTierGroupMember struct {
	// PlayerTag is the player's tag.
	PlayerTag string `json:"playerTag,omitempty"`
	// PlayerName is the player's display name.
	PlayerName string `json:"playerName,omitempty"`
	// ClanTag is the player's clan tag when present.
	ClanTag string `json:"clanTag,omitempty"`
	// ClanName is the player's clan name when present.
	ClanName string `json:"clanName,omitempty"`
	// LeagueTrophies is the player's current legend trophy count.
	LeagueTrophies int `json:"leagueTrophies,omitempty"`
	// AttackWinCount is the player's attack win count in the group.
	AttackWinCount int `json:"attackWinCount,omitempty"`
	// AttackLoseCount is the player's attack loss count in the group.
	AttackLoseCount int `json:"attackLoseCount,omitempty"`
	// DefenseWinCount is the player's defense win count in the group.
	DefenseWinCount int `json:"defenseWinCount,omitempty"`
	// DefenseLoseCount is the player's defense loss count in the group.
	DefenseLoseCount int `json:"defenseLoseCount,omitempty"`
}

LeagueTierGroupMember is one player in a legend league group.

type LegendStatistics

type LegendStatistics struct {
	// LegendTrophies is the player's lifetime legend trophy count.
	LegendTrophies int `json:"legendTrophies"`
	// BestSeason is the player's best legend season.
	BestSeason *Season `json:"bestSeason"`
	// PreviousSeason is the player's previous legend season.
	PreviousSeason *Season `json:"previousSeason"`
	// BestVersusSeason is the player's legacy best Builder Base season.
	BestVersusSeason *Season `json:"bestVersusSeason"`
	// CurrentSeason is the player's current legend season progress.
	CurrentSeason *Season `json:"currentSeason"`
}

LegendStatistics contains a player's legend trophies and season snapshots.

type Limiter added in v0.1.13

type Limiter struct {
	// contains filtered or unexported fields
}

Limiter gates request starts with a strict rolling one-second window and also caps concurrent in-flight work.

func NewLimiter added in v0.1.13

func NewLimiter(rps, maxInFlight int) (*Limiter, error)

NewLimiter creates a limiter. If maxInFlight is zero or negative, rps is used as the in-flight limit.

func (*Limiter) Acquire added in v0.1.13

func (l *Limiter) Acquire(ctx context.Context) (func(), error)

Acquire waits until starting one more operation stays within both the RPS and in-flight limits. The returned release function must be called once the operation finishes.

type Location

type Location struct {
	// ID is the numeric location identifier.
	ID int `json:"id"`
	// Name is the English location name.
	Name string `json:"name"`
	// IsCountry reports whether the location is a country.
	IsCountry bool `json:"isCountry"`
	// CountryCode is the ISO-style country code when the location is a country.
	CountryCode string `json:"countryCode"`
	// Localised is the API-provided localized display name.
	Localised string `json:"localizedName"`
	// contains filtered or unexported fields
}

Location is a country or global location used by ranking endpoints.

func (Location) RetryAfter

func (m Location) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type Maintenance

type Maintenance struct{ *HTTPException }

Maintenance represents a 503 maintenance response from the API.

type NotFound

type NotFound struct{ *HTTPException }

NotFound represents a 404 response from the API.

type PageOptions added in v0.1.13

type PageOptions struct {
	// Limit controls the requested page size.
	Limit int
	// Before is the backward pagination cursor.
	Before string
	// After is the forward pagination cursor.
	After string
}

PageOptions contains the optional cursor pagination values used by list endpoints.

type Pet

type Pet struct {
	// Name is the pet display name.
	Name string `json:"name"`
	// Level is the player's current level or the selected static level.
	Level int `json:"level"`
	// MaxLevel is the maximum level available for the player or in static data.
	MaxLevel int `json:"maxLevel"`
	// Village identifies the pet's village.
	Village string `json:"village"`
}

Pet is a hero pet from a player response.

func (Pet) Static

func (p Pet) Static(c *Client) *StaticUnit

Static returns the embedded static-data record matching this pet's name and level.

type Player

type Player struct {
	// Tag is the player's Clash tag.
	Tag string `json:"tag,omitempty"`
	// Name is the player's current display name.
	Name string `json:"name,omitempty"`
	// ExpLevel is the player's experience level.
	ExpLevel int `json:"expLevel,omitempty"`
	// Trophies is the player's current home village trophy count.
	Trophies int `json:"trophies,omitempty"`
	// BestTrophies is the player's all-time best home village trophy count.
	BestTrophies int `json:"bestTrophies,omitempty"`
	// WarStars is the player's lifetime war star count.
	WarStars int `json:"warStars,omitempty"`
	// TownHall is the player's home village Town Hall level.
	TownHall int `json:"townHallLevel,omitempty"`
	// TownHallWeapon is the weapon level for Town Hall levels that have one.
	TownHallWeapon int `json:"townHallWeaponLevel,omitempty"`
	// BuilderHall is the player's Builder Hall level.
	BuilderHall int `json:"builderHallLevel,omitempty"`
	// BestBuilderBaseTrophies is the all-time best Builder Base trophy count.
	BestBuilderBaseTrophies int `json:"bestBuilderBaseTrophies,omitempty"`
	// VersusAttackWins is the legacy Builder Base attack-win field.
	VersusAttackWins int `json:"versusBattleWins,omitempty"`
	// Donations is the number of troops donated this season.
	Donations int `json:"donations,omitempty"`
	// Received is the number of donated troops received this season.
	Received int `json:"donationsReceived,omitempty"`
	// ClanCapitalContributions is the lifetime Clan Capital contribution count.
	ClanCapitalContributions int `json:"clanCapitalContributions,omitempty"`
	// ClanRank is the player's current rank inside their clan.
	ClanRank int `json:"clanRank,omitempty"`
	// ClanPreviousRank is the player's previous rank inside their clan.
	ClanPreviousRank int `json:"previousClanRank,omitempty"`
	// VersusTrophies is the legacy Builder Base trophy field.
	VersusTrophies int `json:"versusTrophies,omitempty"`
	// BuilderBaseTrophies is the player's current Builder Base trophy count.
	BuilderBaseTrophies int `json:"builderBaseTrophies,omitempty"`
	// LeagueTier is the player's home village league.
	LeagueTier League `json:"leagueTier,omitempty"`
	// BuilderBaseLeague is the player's Builder Base league.
	BuilderBaseLeague *League `json:"builderBaseLeague,omitempty"`
	// Role is the player's role in their current clan.
	Role Role `json:"role,omitempty"`
	// Clan is the compact clan object for the player's current clan.
	Clan *PlayerClan `json:"clan,omitempty"`
	// CurrentLeagueGroupTag is the active legend league group tag when present.
	CurrentLeagueGroupTag string `json:"currentLeagueGroupTag,omitempty"`
	// CurrentLeagueSeasonID is the active legend league season ID when present.
	CurrentLeagueSeasonID int `json:"currentLeagueSeasonId,omitempty"`
	// PreviousLeagueGroupTag is the previous legend league group tag when
	// present.
	PreviousLeagueGroupTag string `json:"previousLeagueGroupTag,omitempty"`
	// PreviousLeagueSeasonID is the previous legend league season ID when
	// present.
	PreviousLeagueSeasonID int `json:"previousLeagueSeasonId,omitempty"`
	// LegendStatistics contains legend trophies and seasonal legend finishes.
	LegendStatistics *LegendStatistics `json:"legendStatistics,omitempty"`
	// Labels are public player labels.
	Labels []Label `json:"labels,omitempty"`
	// Achievements contains achievement progress for both villages and Clan
	// Capital.
	Achievements []Achievement `json:"achievements,omitempty"`
	// Troops contains unlocked troops with current and max levels.
	Troops []Troop `json:"troops,omitempty"`
	// Heroes contains unlocked heroes with current and max levels.
	Heroes []Hero `json:"heroes,omitempty"`
	// Spells contains unlocked spells with current and max levels.
	Spells []Spell `json:"spells,omitempty"`
	// HeroEquipment contains unlocked hero equipment with current and max levels.
	HeroEquipment []Equipment `json:"heroEquipment,omitempty"`
	// contains filtered or unexported fields
}

Player is the full player profile returned by GetPlayer.

func (*Player) BuilderTroops

func (p *Player) BuilderTroops() []Troop

BuilderTroops returns troops that belong to Builder Base.

func (*Player) GetAchievement

func (p *Player) GetAchievement(name string) *Achievement

GetAchievement returns the achievement with the provided display name.

func (*Player) GetHero

func (p *Player) GetHero(name string) *Hero

GetHero returns the hero with the provided display name.

func (*Player) GetSpell

func (p *Player) GetSpell(name string) *Spell

GetSpell returns the spell with the provided display name.

func (*Player) GetTroop

func (p *Player) GetTroop(name string) *Troop

GetTroop returns the troop with the provided display name.

func (*Player) HomeTroops

func (p *Player) HomeTroops() []Troop

HomeTroops returns troops that belong to the home village.

Older API responses may omit Village for home-village troops, so an empty village is treated as home.

func (Player) RetryAfter

func (m Player) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type PlayerClan

type PlayerClan struct {
	// Tag is the clan tag, including the leading # when returned by the API.
	Tag string `json:"tag,omitempty"`
	// Name is the clan display name.
	Name string `json:"name,omitempty"`
	// Level is the clan level.
	Level int `json:"clanLevel,omitempty"`
	// Badge contains the clan badge image URLs.
	Badge Badge `json:"badgeUrls,omitempty"`
}

PlayerClan is the compact clan object embedded in player responses.

type PlayerHouseElement

type PlayerHouseElement struct {
	// ID is the cosmetic element identifier.
	ID int `json:"id"`
	// Type is the cosmetic element type.
	Type string `json:"type"`
}

PlayerHouseElement is one cosmetic element of a player's house.

type PrivateWarLog

type PrivateWarLog struct{ *HTTPException }

PrivateWarLog represents the private-war-log 403 response.

type RaidAttack

type RaidAttack struct {
	// AttackerTag can be populated by callers that join attacks to raid members.
	AttackerTag string `json:"-"`
	// AttackerName can be populated by callers that join attacks to raid
	// members.
	AttackerName string `json:"-"`
	// Stars is the star count earned by this district attack.
	Stars int `json:"stars,omitempty"`
	// Destruction is the destruction percentage earned by this district attack.
	Destruction float64 `json:"destructionPercent,omitempty"`
}

RaidAttack is one attack against a Clan Capital district.

type RaidClan

type RaidClan struct {
	// AttackCount is the number of attacks used in this raid.
	AttackCount int `json:"attackCount,omitempty"`
	// DistrictCount is the number of districts available.
	DistrictCount int `json:"districtCount,omitempty"`
	// DestroyedDistrictCount is the number of districts destroyed.
	DestroyedDistrictCount int `json:"districtsDestroyed,omitempty"`
	// Districts contains district-level attack details.
	Districts []RaidDistrict `json:"districts,omitempty"`
	// Attacker is set on attack-log entries.
	Attacker *struct {
		Tag   string `json:"tag,omitempty"`
		Name  string `json:"name,omitempty"`
		Level int    `json:"level,omitempty"`
	} `json:"attacker,omitempty"`
	// Defender is set on defense-log entries.
	Defender *struct {
		Tag   string `json:"tag,omitempty"`
		Name  string `json:"name,omitempty"`
		Level int    `json:"level,omitempty"`
	} `json:"defender,omitempty"`
}

RaidClan describes one opposing clan entry in a raid attack or defense log.

Attack log entries use Attacker for the clan being attacked by the requested clan. Defense log entries use Defender for the clan that attacked the requested clan.

func (RaidClan) Level

func (r RaidClan) Level() int

Level returns the attacker or defender clan level for this raid clan entry.

func (RaidClan) Name

func (r RaidClan) Name() string

Name returns the attacker or defender name for this raid clan entry.

func (RaidClan) Tag

func (r RaidClan) Tag() string

Tag returns the attacker or defender tag for this raid clan entry.

type RaidDistrict

type RaidDistrict struct {
	// ID is the district identifier.
	ID int `json:"id,omitempty"`
	// Name is the district display name.
	Name string `json:"name,omitempty"`
	// HallLevel is the district hall level.
	HallLevel int `json:"districtHallLevel,omitempty"`
	// Destruction is the final destruction percentage for the district.
	Destruction float64 `json:"destructionPercent,omitempty"`
	// AttackCount is the number of attacks used against the district.
	AttackCount int `json:"attackCount,omitempty"`
	// Looted is the total capital gold looted from the district.
	Looted int `json:"totalLooted,omitempty"`
	// Attacks contains individual attacks against the district.
	Attacks []RaidAttack `json:"attacks,omitempty"`
}

RaidDistrict describes one district in a raid attack or defense log.

type RaidLogEntry

type RaidLogEntry struct {
	// State is the raid weekend state.
	State string `json:"state,omitempty"`
	// TotalLoot is the clan's total capital gold looted.
	TotalLoot int `json:"capitalTotalLoot,omitempty"`
	// CompletedRaidCount is the number of completed raids.
	CompletedRaidCount int `json:"raidsCompleted,omitempty"`
	// AttackCount is the total number of attacks used by the clan.
	AttackCount int `json:"totalAttacks,omitempty"`
	// DestroyedDistrictCount is the number of enemy districts destroyed.
	DestroyedDistrictCount int `json:"enemyDistrictsDestroyed,omitempty"`
	// OffensiveReward is the offensive raid medal reward.
	OffensiveReward int `json:"offensiveReward,omitempty"`
	// DefensiveReward is the defensive raid medal reward.
	DefensiveReward int `json:"defensiveReward,omitempty"`
	// StartTime is when the raid weekend started.
	StartTime *Timestamp `json:"startTime,omitempty"`
	// EndTime is when the raid weekend ended.
	EndTime *Timestamp `json:"endTime,omitempty"`
	// AttackLog contains raids made by the requested clan.
	AttackLog []RaidClan `json:"attackLog,omitempty"`
	// DefenseLog contains raids made against the requested clan.
	DefenseLog []RaidClan `json:"defenseLog,omitempty"`
	// Members contains member-level attack and loot totals.
	Members []RaidMember `json:"members,omitempty"`
	// contains filtered or unexported fields
}

RaidLogEntry is one Clan Capital raid weekend log entry.

func (*RaidLogEntry) GetMember

func (r *RaidLogEntry) GetMember(tag string) *RaidMember

GetMember returns the raid member with the provided tag.

func (RaidLogEntry) RetryAfter

func (m RaidLogEntry) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type RaidMember

type RaidMember struct {
	// Tag is the member's player tag.
	Tag string `json:"tag,omitempty"`
	// Name is the member's display name.
	Name string `json:"name,omitempty"`
	// AttackCount is the number of attacks used.
	AttackCount int `json:"attacks,omitempty"`
	// AttackLimit is the normal attack limit.
	AttackLimit int `json:"attackLimit,omitempty"`
	// BonusAttackLimit is the number of bonus attacks available.
	BonusAttackLimit int `json:"bonusAttackLimit,omitempty"`
	// CapitalResourcesLooted is the capital gold looted by the member.
	CapitalResourcesLooted int `json:"capitalResourcesLooted,omitempty"`
}

RaidMember is one clan member's contribution in a raid weekend.

type RankedClan

type RankedClan struct {
	Clan
	// Rank is the current ranking position.
	Rank int `json:"rank,omitempty"`
	// PreviousRank is the previous ranking position when the API provides it.
	PreviousRank int `json:"previousRank,omitempty"`
}

RankedClan is a clan ranking entry.

func (RankedClan) RetryAfter

func (m RankedClan) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type RankedPlayer

type RankedPlayer struct {
	Player
	// League is the player's ranking league when the endpoint includes it.
	League League `json:"league,omitempty"`
	// AttackWins is the player's attack win count in the ranking.
	AttackWins int `json:"attackWins,omitempty"`
	// DefenseWins is the player's defense win count in the ranking.
	DefenseWins int `json:"defenseWins,omitempty"`
	// Rank is the current ranking position.
	Rank int `json:"rank,omitempty"`
	// PreviousRank is the previous ranking position when the API provides it.
	PreviousRank int `json:"previousRank,omitempty"`
}

RankedPlayer is a player ranking entry.

func (RankedPlayer) RetryAfter

func (m RankedPlayer) RetryAfter() int

RetryAfter returns the number of seconds the API says this response can be cached, derived from Cache-Control max-age.

type RequestOptions

type RequestOptions struct {
	// LookupCache allows a GET request to return a fresh cached response.
	LookupCache bool
	// UpdateCache allows a successful GET request to store or replace a cached
	// response.
	UpdateCache bool
	// SkipAuth prevents Do from adding an Authorization header.
	SkipAuth bool
}

RequestOptions controls per-request behavior for HTTPClient.Do.

type Resource

type Resource struct {
	// Name is the resource name, such as gold, elixir, or dark elixir.
	Name string `json:"name,omitempty"`
	// Amount is the resource quantity.
	Amount int `json:"amount,omitempty"`
}

Resource is a named resource amount in a player battle log entry.

type Role

type Role string

Role is a member's role inside a clan.

const (
	// RoleMember is a regular clan member.
	RoleMember Role = "member"
	// RoleElder is a clan elder. The Clash API value is "admin".
	RoleElder Role = "admin"
	// RoleCoLeader is a clan co-leader.
	RoleCoLeader Role = "coLeader"
	// RoleLeader is the clan leader.
	RoleLeader Role = "leader"
)

type SearchClansRequest

type SearchClansRequest struct {
	// Name filters clans by name.
	Name string
	// WarFrequency filters clans by declared war frequency.
	WarFrequency string
	// LocationID filters clans by location ID.
	LocationID int
	// MinMembers filters out clans with fewer members.
	MinMembers int
	// MaxMembers filters out clans with more members.
	MaxMembers int
	// MinClanPoints filters by minimum clan points.
	MinClanPoints int
	// MinClanLevel filters by minimum clan level.
	MinClanLevel int
	// LabelIDs filters by one or more clan label IDs.
	LabelIDs []int
	// Limit controls the number of results requested.
	Limit int
	// Before is a pagination cursor.
	Before string
	// After is a pagination cursor.
	After string
}

SearchClansRequest contains optional filters for SearchClans.

Zero values are omitted from the query string, matching Clash API search behavior.

type Season

type Season struct {
	// ID is the season identifier returned by the API.
	ID string `json:"id"`
	// Rank is the player's season rank.
	Rank int `json:"rank"`
	// Trophies is the player's trophy count for the season.
	Trophies int `json:"trophies"`
}

Season describes one ranked season placement.

type SeasonWindow

type SeasonWindow struct {
	// SeasonID is the season identifier in YYYY-MM form.
	SeasonID string
	// StartTime is the inclusive season start time in UTC.
	StartTime time.Time
	// EndTime is the exclusive season end time in UTC.
	EndTime time.Time
}

func GetSeason

func GetSeason(timestamp time.Time, forward bool) SeasonWindow

GetSeason returns the trophy season window containing timestamp.

Passing a zero timestamp uses the current UTC time. Before the 2025 season calendar change, seasons end on the last Monday of the month at 05:00 UTC. From the September 2025 transition onward, seasons follow fixed 28 day windows.

func GetSeasonByID

func GetSeasonByID(seasonID string) (SeasonWindow, error)

GetSeasonByID returns the trophy season window for a YYYY-MM season ID.

Example
package main

import (
	"fmt"
	"log"
	"time"

	clashy "github.com/clashkinginc/clashy.go"
)

func main() {
	season, err := clashy.GetSeasonByID("2025-09")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(season.SeasonID)
	fmt.Println(season.StartTime.Format(time.RFC3339))
	fmt.Println(season.EndTime.Format(time.RFC3339))

}
Output:
2025-09
2025-08-25T05:00:00Z
2025-10-06T05:00:00Z

type Spell

type Spell struct {
	// Name is the spell display name.
	Name string `json:"name"`
	// Level is the player's current level or the selected static level.
	Level int `json:"level"`
	// MaxLevel is the maximum level available for the player or in static data.
	MaxLevel int `json:"maxLevel"`
	// Village identifies the spell's village when static data provides one.
	Village string `json:"village"`
}

Spell is a spell from a player response.

func (Spell) Static

func (s Spell) Static(c *Client) *StaticUnit

Static returns the embedded static-data record matching this spell's name and level.

type SpellCount

type SpellCount struct {
	// Spell is the parsed spell.
	Spell Spell
	// Quantity is the requested spell count.
	Quantity int
}

SpellCount pairs a spell with a quantity from an army link.

type StaticData

type StaticData struct {
	// contains filtered or unexported fields
}

StaticData is the parsed and indexed ClashKing static data embedded in the package.

func LoadStaticData

func LoadStaticData() (*StaticData, error)

LoadStaticData parses the embedded static-data files once and returns the shared indexed result.

func (*StaticData) LookupByID

func (s *StaticData) LookupByID(id int) map[string]any

LookupByID returns a static-data entry by numeric static ID.

func (*StaticData) LookupByName

func (s *StaticData) LookupByName(name, section, village string) map[string]any

LookupByName returns a static-data entry by display name, section, and village.

The lookup is case-insensitive. The section should match a top-level static data section such as "troops", "spells", "heroes", "pets", or "equipment".

func (*StaticData) Section added in v0.1.13

func (s *StaticData) Section(name string) []map[string]any

Section returns an isolated copy of one top-level static-data section.

func (*StaticData) Sections added in v0.1.13

func (s *StaticData) Sections() map[string][]map[string]any

Sections returns an isolated copy of all top-level static-data sections.

func (*StaticData) Translation added in v0.1.13

func (s *StaticData) Translation(id string) map[string]string

Translation returns an isolated language map for one translation ID.

func (*StaticData) Translations

func (s *StaticData) Translations() map[string]map[string]string

Translations returns an isolated copy of all translations.

type StaticUnit

type StaticUnit struct {
	// Name is the unit or equipment display name.
	Name string `json:"name"`
	// Level is the selected level for this static lookup.
	Level int `json:"level"`
	// MaxLevel is the maximum level found in static data.
	MaxLevel int `json:"maxLevel"`
	// Village identifies the village this object belongs to.
	Village string `json:"village"`
	// UpgradeCost is the cost for the selected level when static data includes
	// it.
	UpgradeCost int `json:"upgradeCost"`
	// UpgradeTime is the upgrade duration for the selected level when static data
	// includes it.
	UpgradeTime time.Duration `json:"upgradeTime"`
	// Rarity is populated for hero equipment when static data includes it.
	Rarity string `json:"rarity,omitempty"`
}

StaticUnit contains normalized static-data fields shared by troops, spells, heroes, pets, and hero equipment.

type TimeDelta

type TimeDelta struct {
	// Duration is the underlying Go duration.
	time.Duration
}

TimeDelta represents an elapsed duration.

type Timestamp

type Timestamp struct {
	// RawTime is the original API timestamp.
	//
	//	20060102T150405.000Z
	RawTime string
	// Time is the parsed UTC time.
	Time time.Time
}

Timestamp stores both the raw Clash API timestamp string and its parsed time.

func (Timestamp) After

func (t Timestamp) After(other Timestamp) bool

After reports whether this timestamp occurs after another timestamp.

func (Timestamp) Before

func (t Timestamp) Before(other Timestamp) bool

Before reports whether this timestamp occurs before another timestamp.

func (Timestamp) MarshalJSON added in v0.1.13

func (t Timestamp) MarshalJSON() ([]byte, error)

MarshalJSON encodes Timestamp using the Clash API timestamp format.

func (Timestamp) SecondsUntil

func (t Timestamp) SecondsUntil() int

SecondsUntil returns the number of whole seconds from now until the timestamp.

func (*Timestamp) UnmarshalJSON

func (t *Timestamp) UnmarshalJSON(data []byte) error

UnmarshalJSON parses Clash API timestamp strings into Timestamp values.

type Translation

type Translation struct {
	// ID is the translation identifier.
	ID string `json:"id"`
	// English is the EN translation value.
	English string `json:"EN"`
	// Languages maps language codes to translated strings.
	Languages map[string]string `json:"-"`
}

Translation contains one static-data translation entry.

func (*Translation) UnmarshalJSON

func (t *Translation) UnmarshalJSON(data []byte) error

UnmarshalJSON stores all language entries and promotes EN into English.

type Troop

type Troop struct {
	// Name is the troop display name.
	Name string `json:"name"`
	// Level is the player's current level or the selected static level.
	Level int `json:"level"`
	// MaxLevel is the maximum level available for the player's Town Hall or in
	// static data.
	MaxLevel int `json:"maxLevel"`
	// Village identifies home or Builder Base troops.
	Village string `json:"village"`
	// SuperTroopIsActive reports whether a super troop boost is active.
	SuperTroopIsActive bool `json:"superTroopIsActive"`
}

Troop is a troop from a player response.

func (Troop) IsBuilderBase

func (t Troop) IsBuilderBase() bool

IsBuilderBase reports whether the troop belongs to Builder Base.

func (Troop) IsHomeBase

func (t Troop) IsHomeBase() bool

IsHomeBase reports whether the troop belongs to the home village.

func (Troop) IsSuperTroop

func (t Troop) IsSuperTroop() bool

IsSuperTroop reports whether the troop name is one of the known super troops.

func (Troop) Static

func (t Troop) Static(c *Client) *StaticUnit

Static returns the embedded static-data record matching this troop's name, village, and level.

type TroopCount

type TroopCount struct {
	// Troop is the parsed troop.
	Troop Troop
	// Quantity is the requested troop count.
	Quantity int
}

TroopCount pairs a troop with a quantity from an army link.

type VillageType

type VillageType string

VillageType identifies the village or game area for static data and units.

const (
	// VillageHome is the home village.
	VillageHome VillageType = "home"
	// VillageBuilderBase is Builder Base.
	VillageBuilderBase VillageType = "builderBase"
	// VillageClanCapital is Clan Capital.
	VillageClanCapital VillageType = "clanCapital"
)

type WarAttack

type WarAttack struct {
	// Order is the attack order assigned by the API.
	Order int `json:"order,omitempty"`
	// AttackerTag is the player tag of the attacker.
	AttackerTag string `json:"attackerTag,omitempty"`
	// DefenderTag is the player tag of the defender.
	DefenderTag string `json:"defenderTag,omitempty"`
	// Stars is the number of stars earned by the attack.
	Stars int `json:"stars,omitempty"`
	// Destruction is the destruction percentage earned by the attack.
	Destruction float64 `json:"destructionPercentage,omitempty"`
	// Duration is the attack duration in seconds.
	Duration int `json:"duration,omitempty"`
}

WarAttack is one attack inside a classic war or Clan War League war.

type WarClan

type WarClan struct {
	// Tag is the clan tag.
	Tag string `json:"tag,omitempty"`
	// Name is the clan name.
	Name string `json:"name,omitempty"`
	// Badge contains clan badge image URLs.
	Badge Badge `json:"badgeUrls,omitempty"`
	// Level is the clan level.
	Level int `json:"clanLevel,omitempty"`
	// Attacks is the number of attacks used by this clan.
	Attacks int `json:"attacks,omitempty"`
	// Stars is the total stars earned by this clan.
	Stars int `json:"stars,omitempty"`
	// Destruction is the total destruction percentage earned by this clan.
	Destruction float64 `json:"destructionPercentage,omitempty"`
	// ExpEarned is clan XP earned by this war when the endpoint includes it.
	ExpEarned int `json:"expEarned,omitempty"`
	// Members is the war roster for this side.
	Members []ClanWarMember `json:"members,omitempty"`
}

WarClan is one clan side of a classic war or CWL war.

type WarResult

type WarResult string

WarResult is the requested clan's result in a war log entry.

const (
	// WarResultWin means the requested clan won.
	WarResultWin WarResult = "win"
	// WarResultLose means the requested clan lost.
	WarResultLose WarResult = "lose"
	// WarResultTie means the war ended in a tie.
	WarResultTie WarResult = "tie"
)

type WarRound

type WarRound int

WarRound identifies the logical CWL round requested from GetCurrentWar or GetLeagueWar.

const (
	// PreviousWar selects the previous completed or in-war CWL round.
	PreviousWar WarRound = iota
	// CurrentWar selects the active CWL war, or the latest completed/in-war
	// round when the latest real round is only preparation.
	CurrentWar
	// CurrentPreparation selects the upcoming CWL preparation round when one is
	// available.
	CurrentPreparation
)

type WarState

type WarState string

WarState is the lifecycle state of a classic war or CWL war.

const (
	// WarStateNotInWar means the clan is not in a regular war.
	WarStateNotInWar WarState = "notInWar"
	// WarStatePreparation means the war is in preparation day.
	WarStatePreparation WarState = "preparation"
	// WarStateInWar means battle day is active.
	WarStateInWar WarState = "inWar"
	// WarStateEnded means the war has ended.
	WarStateEnded WarState = "warEnded"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL