Unofficial client for the AION 2 website's JSON API. Supports KR, TW and Global.
import aion2 "github.com/nuriland/aion2-api"
kr, _ := aion2.New(aion2.ConfigOpts{Region: aion2.RegionKR, Locale: aion2.LocaleEN})
tw, _ := aion2.New(aion2.ConfigOpts{Region: aion2.RegionTW, Locale: aion2.LocaleEN})
eu, _ := aion2.New(aion2.ConfigOpts{Region: aion2.RegionEU}) // defaults to region's localeSince Global's launch, KR's site API answers every route with 404 from outside Korea. Those calls return
ErrNoRoute, and a Logger gets a warning. KR's boards and styleshop still work.
Global is five shards, each its own region: RegionNAE, RegionNAW, RegionEU, RegionSA and RegionAsia.
Locales are LocaleEN (the default), LocaleDE, LocaleES, LocaleFR, LocaleJA and LocalePTBR.
KR takes LocaleKO and LocaleEN, TW those two and LocaleZHTW. Anything else is ErrUnsupportedLocale due to NC's API not supporting them.
res, _ := eu.SearchCharacters(ctx, aion2.CharacterSearch{Keyword: "a"})
ch, _ := eu.Character(ctx, res.Items[0].Ref)Global has no item catalog and no player boards. NC also took Item's route off Global around Oct 12 2026,
though its own site still calls it, so Supports(aion2.FeatureItems) is false there.
servers, _ := kr.Servers(ctx) // 42 on KR, 36 on TW, a handful per Global shard
classes, _ := kr.Classes(ctx)res, _ := tw.SearchCharacters(ctx, aion2.CharacterSearch{
Keyword: "a",
RaceID: 1, // 1 Ely, 2 Asmo
ServerID: 1001, // optional
ClassIDs: []int{2}, // optional
})
ref := res.Items[0].Ref
ch, _ := tw.Character(ctx, ref)
eq, _ := tw.Equipment(ctx, ref)
item, _ := tw.EquippedItem(ctx, ref, eq.Slots[0])
board, _ := tw.Daevanion(ctx, ref, ch.Daevanion[0].ID)
fmt.Println(ch.Profile.Name, ch.Profile.CombatPower, len(eq.Slots))
for hit, err := range tw.Characters(ctx, aion2.CharacterSearch{Keyword: "a", RaceID: 1}) {
if err != nil {
return err
}
fmt.Println(hit.Name, hit.Level)
}Got a profile URL instead? Paste the id straight in:
ch, _ := kr.Character(ctx, aion2.CharacterRef{
ServerID: 1001,
CharacterID: "<the id from the profile URL>",
})item, _ := kr.Item(ctx, 110120001) // the definition at +0 with its stats, one request
page, _ := tw.SearchItems(ctx, aion2.ItemSearch{
Query: "巨劍",
Grade: "Epic",
Category: "Equip_Weapon",
SubCategory: "Greatsword",
ClassID: 2,
Size: 200,
})
for it, err := range tw.Items(ctx, aion2.ItemSearch{Grade: "Epic", Category: "Equip_Weapon"}) {
if err != nil {
return err
}
fmt.Println(it.ID, it.Name)
}
names, _ := tw.SuggestItems(ctx, "巨劍") // the item page's autocomplete, up to 10 names, no ids
grades, _ := tw.ItemGrades(ctx) // the ids ItemSearch.Grade takes, with localized names
categories, _ := tw.ItemCategories(ctx) // same for Category / SubCategoryNC took the public boards down in 2026 and until they return, every board answers ErrNoSeason.
board, err := kr.Rankings(ctx, aion2.RankingQuery{ContentsType: aion2.RankingAbyss, ServerID: 1001})
if errors.Is(err, aion2.ErrNoSeason) {
return nil
}
fmt.Println(board.Season.SeasonNo, len(board.Entries))top, _ := kr.TopStyles(ctx, aion2.StyleTop{Period: "DAY_30", SortBy: "LIKES"})
page, _ := kr.SearchStyles(ctx, aion2.StyleSearch{Field: "item", Keyword: "대검", Gender: "MALE", Size: 20})
for look, err := range kr.Styles(ctx, aion2.StyleSearch{Tags: []string{"러블리"}}) { // KR and TW spell their tag codes in their own language
if err != nil {
return err
}
fmt.Println(look.Title, look.Author.Name, look.Images[0])
}
tags, _ := kr.StyleTags(ctx)
lovely, _ := kr.SearchStyles(ctx, aion2.StyleSearch{Tags: []string{tags[0].Code}, Class: "GLADIATOR"})
style, _ := kr.Style(ctx, top[0].ID)
replies, _ := kr.StyleComments(ctx, top[0].ID)for note, err := range kr.Posts(ctx, aion2.BoardPatchNotes) {
if err != nil {
return err
}
if note.PostedAt.Before(since) {
break
}
latest, _ := kr.Post(ctx, aion2.BoardPatchNotes, note.ID)
fmt.Println(latest.Title, latest.PostedAt, len(latest.HTML))
}
pinned, _ := kr.PinnedPosts(ctx, aion2.BoardNotices)for post, err := range tw.Posts(ctx, aion2.BoardFree) {
if err != nil {
return err
}
if post.Author == nil { // if a post is made by NC staff the author is empty
continue
}
ch, _ := tw.Character(ctx, post.Author.Ref)
comments, _ := tw.Comments(ctx, aion2.BoardFree, post.ID)
break
}aion2-mcp serves this API as MCP tools.