Table of Contents

Building a Lobby Browser for Age of Empires II: Definitive Edition

This guide covers how to interact with the Worlds Edge Link API to build custom lobby browsers and spectator tools for Age of Empires games.

Overview

The Worlds Edge Link API provides two main approaches for accessing lobby data:

For simpler integration, you can also use the aoe2lobby.com WebSocket API which provides real-time updates without polling.

Quick Start: Community API

Basic Lobby Listing

For a simple lobby browser, use the community endpoint /advertisement/findAdvertisements :

GET https://aoe-api.worldsedgelink.com/community/advertisement/findAdvertisements?title=age2

Features:

This is sufficient for most lobby browsing use cases.

Advanced: Game API (Authenticated)

For accessing ongoing matches and spectator features, you'll need to authenticate using Steam.

We provide a reference implementation written in Python that you may want to have a look at.

Prerequisites

Authentication Flow

Step 1: Create Encrypted App Ticket

const SteamUser = require('steam-user');
const client = new SteamUser();
 
// Login to Steam first (with your credentials)
await client.logOn({...});
 
// Create encrypted app ticket
const APP_ID = 813780; // AoE2:DE
const eticket = await client.createEncryptedAppTicket(
    APP_ID, 
    Buffer.from("RLINK")  // Important: Include RLINK buffer
);
 
// Encode for API use
const auth = encodeURIComponent(
    eticket.encryptedAppTicket.toString('base64')
);

Important Notes:

Step 2: Platform Login

const url = `https://aoe-api.worldsedgelink.com/game/login/platformlogin?`
    + `accountType=STEAM`
    + `&activeMatchId=-1`
    + `&alias=${alias}`
    + `&appID=${APP_ID}`
    + `&auth=${auth}`  // Your encoded ticket from Step 1
    + `&callNum=0`
    + `&clientLibVersion=190`  // Update as game updates
    + `&country=US`
    + `&installationType=windows`
    + `&language=en`
    + `&macAddress=DE-AD-D0-0D-00-00`  // Can be any value
    + `&majorVersion=4.0.0`
    + `&minorVersion=0`
    + `&platformUserID=${steamID}`
    + `&timeoutOverride=0`
    + `&title=age2`;
 
const response = await axios.post(url);
const sessionId = response.data.sessionID; // Save this!

Key Parameters:

Getting Game Build Version

The appBinaryChecksum parameter requires the current game build version. You can obtain this programmatically:

const getBuildVersion = async (appId) => {
    const rss = await fetch(
        `https://store.steampowered.com/feeds/news/app/${appId}/`
    );
    const parser = new XMLParser();
    const feed = parser.parse(await rss.text());
 
    let lastUpdateTitle = feed?.rss?.channel?.item
        ?.map(e => e.title)
        .find(e => e.match(/(update.[0-9]+)/gi));
 
    return parseInt(
        lastUpdateTitle.slice(
            lastUpdateTitle.search(/update/gi) + "update".length
        )
    );
}

Alternatively, check the bottom-left corner when launching the game.

Finding Observable Matches

Once authenticated, query ongoing games:

const url = `https://aoe-api.worldsedgelink.com/game/advertisement/findObservableAdvertisements?`
    + `appBinaryChecksum=${gameVersion}`
    + `&callNum=0`
    + `&count=50`
    + `&dataChecksum=0`
    + `&desc=1`
    + `&matchType_id=0`
    + `&modName=INVALID`
    + `&modDLLChecksum=0`
    + `&modDLLFile=INVALID`
    + `&modVersion=INVALID`
    + `&start=0`
    + `&sortOrder=1`
    + `&versionFlags=56950784`
    + `&sessionID=${sessionId}`
    + `&connect_id=${sessionId}`;
 
const response = await axios.get(url);

Filtering Options

By Player Profiles

&profile_ids=[123456,789012]

Filter matches to only show games with specific player profile IDs.

By Numeric Tags

&numericTagNames=["HasPassword"]
&numericTagValues=[0]

Common tags include:

Response Format

Warning: The Game API returns responses in an obscured array format that is not user-friendly.

// Example response structure
[
    someMetadata,
    [  // Array of matches
        [lobbyId, platformSessionId, ...otherFields],
        [lobbyId, platformSessionId, ...otherFields],
        // etc.
    ]
]

Parsing Help:

Alternative: WebSocket API

For simpler integration, consider using the aoe2lobby.com WebSocket API:

Connection

WebSocket URL:

wss://data.aoe2lobby.com/ws/

The API supports subscribing to different data feeds by sending JSON subscription messages.

Subscription Examples

Subscribe to spectate matches:

{"action":"subscribe","type":"matches","context":"spectate"}

Subscribe to lobby matches:

{"action":"subscribe","type":"matches","context":"lobby"}

Subscribe to specific Elo types:

{"action":"subscribe","type":"elotypes","context":"lobby","ids":["1223","3","4"]}

Subscribe to specific players:

{"action":"subscribe","type":"players","context":"lobby","ids":["3920944"]}

Player status updates include current status, match ID, and Steam lobby ID:

{
  "player_status": {
    "19501096": {
      "status": "lobby",
      "matchid": "412015195",
      "steam_lobbyid": "109775244730862406"
    }
  }
}

Resources

Best Practices

Rate Limiting

Version Management

Authentication

Additional Resources

Documentation & Projects

Community Support

Contributing

This documentation is community-maintained. If you discover new endpoints, parameters, or corrections, please contribute back to help other developers!


Last updated: December 2025
Based on community research and shared knowledge