AION2 Index
Communities

API documentation

v1

Read-only AION 2 character data for community bots and tools.

Introduction

The API returns the public data of an AION 2 Global character. All requests use HTTPS and all responses are JSON. Access is granted per community.

Base URL
https://aion2index.com/api/v1

Request access with your Discord account. Once approved, your API key is created from your panel.

Authentication

Send your API key as a bearer token in the Authorization header of every request.

Header
Authorization: Bearer <your-api-key>

A key is shown once, when it is created. Keep it on your server and never put it in a public repository or a client application. If it leaks, replace it from your panel: the old key stops working at once.

Get a character

GET/characters/{region}/{server}/{name}

Path parameters

NameTypeDescription
regionstringnae NA East, naw NA West, eu Europe, la Latin America, as Asia.
serverstringServer slug, in lower case, as in profile URLs: zikel.
namestringCharacter name, URL-encoded. Not case-sensitive.

Example request

curl "https://aion2index.com/api/v1/characters/nae/zikel/ExampleDaeva" \
  -H "Authorization: Bearer $AION2INDEX_API_KEY"

Response

200 OK
{
  "characterId": "aBcD1234ExampleCharacterId00000000000000000=",
  "name": "ExampleDaeva",
  "region": "nae",
  "regionName": "NA East",
  "server": "Zikel",
  "serverSlug": "zikel",
  "faction": "asmodian",
  "class": "Gladiator",
  "level": 45,
  "itemLevel": 2850,
  "combatPower": 152340,
  "legion": "Example Legion",
  "title": { "name": "Saint of Altgard", "grade": "Unique" },
  "profileUrl": "https://aion2index.com/c/nae/zikel/ExampleDaeva",
  "legionUrl": "https://aion2index.com/legion/nae/zikel/Example%20Legion",
  "updatedAt": "2026-10-30T18:00:00.000Z",
  "fresh": true
}

Fields

FieldTypeDescription
characterIdstringStable identifier. It survives renames, so store it to link a member to a character.
namestringCharacter name.
regionstringRegion code.
regionNamestringRegion name.
serverstringGame server name.
serverSlugstringGame server slug, as used in the request path.
factionstringelyos or asmodian.
classstring | nullClass name.
levelintegerCharacter level.
itemLevelinteger | nullItem level.
combatPowerinteger | nullCombat power.
legionstring | nullLegion name. Null when the character has no legion.
titleobject | nullDisplayed title, with its name and grade. Null when none is displayed.
profileUrlstringCharacter profile on AION2 Index.
legionUrlstring | nullLegion page on AION2 Index.
updatedAtstringISO 8601 time of the last read from the game.
freshbooleanTrue when the data was read from the game within the last minute.

Data freshness

Each request reads the character from the game, unless it was read within the last minute. Requests for the same character within that minute share the same reading.

If the game does not answer within 10 seconds, or during game maintenance, the response carries the saved data with fresh set to false. Check updatedAt to see how old it is.

Verifying members

For access decisions, only accept responses where fresh is true: a member may have changed legion since the saved reading. This example checks faction and legion.

JavaScript
const ALLOWED_LEGIONS = new Set(['Example Legion', 'Allied Legion']);

async function verifyMember(region, server, name) {
  const url = `https://aion2index.com/api/v1/characters/${region}/${server}/${encodeURIComponent(name)}`;
  const response = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.AION2INDEX_API_KEY}` },
  });
  if (response.status === 404) return { ok: false, reason: 'Character not found' };
  if (!response.ok) return { ok: false, reason: 'Try again shortly' };

  const character = await response.json();
  // Saved data may be out of date: never let a member in on it.
  if (!character.fresh) return { ok: false, reason: 'Try again shortly' };
  if (character.faction !== 'asmodian') return { ok: false, reason: 'Wrong faction' };
  if (!ALLOWED_LEGIONS.has(character.legion)) return { ok: false, reason: 'Legion not allowed' };
  return { ok: true, characterId: character.characterId };
}

Proving ownership

Anyone can type a character name. To confirm that a member plays the character, ask them to display a title of your choice in game, wait a minute, and compare it with title.name.

Linking accounts

Store characterId with the Discord account. Unlike the name, it does not change when a character is renamed.

Rate limits

Each key has its own limit per minute, shown in your panel. Requests that pass authentication carry these headers:

HeaderDescription
x-ratelimit-limitRequests allowed per minute for this key.
x-ratelimit-remainingRequests left in the current window.
x-ratelimit-resetUnix time, in seconds, when the window resets.
retry-afterSeconds to wait. Only on 429 responses.

Errors

Errors use standard HTTP status codes and share one format.

Error response
{
  "error": {
    "code": "not_found",
    "message": "No such character."
  }
}
StatusCodeDescription
401missing_keyThe Authorization header is missing or malformed.
401invalid_keyThe API key does not exist.
403key_disabledThe API key was disabled.
404not_foundUnknown region, server or character, or a hidden character.
429rate_limitedThe key is over its limit. Wait for the time in retry-after.
429upstream_unavailableThe game data is not answering and nothing is saved. Retry after the time in retry-after.

Enjoying AION2 Index? Your support helps keep it free for every Daeva.

Support us