# How to Integrate with the Saddlebag Exchange API in Azeroth Auction Assassin (AAA)

> Learn how to integrate Saddlebag Exchange API with Azeroth Auction Assassin. Our Python client handles auth, fallback logic, and link generation for seamless integration.

- Repository: [FF14 Advanced Market Search/azerothauctionassassin](https://github.com/ff14-advanced-market-search/azerothauctionassassin)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Azeroth Auction Assassin integrates with the Saddlebag Exchange API through a Python HTTP client layer in [`utils/api_requests.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/api_requests.py) that handles authentication via `WOW_DISCORD_CONSENT`, implements GitHub fallback logic for offline resilience, and provides utility functions for generating user-facing links.**

The Azeroth Auction Assassin (AAA) open-source project provides a complete integration pattern with the Saddlebag Exchange API, enabling real-time World of Warcraft auction data retrieval. This integration leverages a three-layer architecture comprising HTTP client utilities, token-based authentication, and UI helper functions to ensure reliable data access even when the primary API experiences downtime.

## Understanding the Saddlebag Exchange API Integration Architecture

The integration is split into three logical layers that handle distinct responsibilities within the AAA codebase.

### HTTP Client Layer in utils/api_requests.py

The [`utils/api_requests.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/api_requests.py) file defines the core communication layer with the Saddlebag Exchange API. It sets the base URL constant `SADDLEBAG_URL = "https://api.saddlebagexchange.com"` and provides helper functions such as `get_itemnames()`, `get_ilvl_items()`, and `get_update_timers_backup()`.

Every POST request to a Saddlebag endpoint includes a JSON payload containing the constant `WOW_DISCORD_CONSENT`. This string is required by the API to confirm that the caller respects the "once-per-hour" rate-limit policy. If a request fails, the module automatically falls back to downloading the same data from the repository's `StaticData` folder on GitHub using `RAW_GITHUB_BACKUP_PATH`, ensuring the UI remains functional during API outages.

### Authentication Flow in AzerothAuctionAssassin.py

The main application entry point in [`AzerothAuctionAssassin.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/AzerothAuctionAssassin.py) handles token-based authentication for protected endpoints. It stores the token endpoint in `self.token_auth_url = "https://api.saddlebagexchange.com/api/wow/checkmegatoken"` and uses this on startup to obtain a short-lived JWT-like token.

The application performs a POST to this URL, passing `WOW_DISCORD_CONSENT` in the payload. The response contains a token that must be attached as an `Authorization: Bearer <token>` header for subsequent "mega-item-names" requests. The UI thread `Item_And_Pet_Statistics.run` calls `https://api.saddlebagexchange.com/api/wow/megaitemnames` with this token implicitly via the shared consent payload, and the token refreshes automatically when authentication errors are detected.

### UI Helper Functions in utils/helpers.py

The [`utils/helpers.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/helpers.py) file provides the `create_saddlebag_link(item_id)` function, which builds user-friendly URLs like `https://saddlebagexchange.com/wow/item-data/12345`. This helper is utilized by both the Python backend and the Electron frontend to insert "Saddlebag links" into Discord embeds and UI alerts.

## Step-by-Step Runtime Integration Flow

Understanding how these components interact at runtime clarifies the complete integration pattern:

1. **Application Startup** → `App.__init__` initializes the token URL (`self.token_auth_url`) and sets up the API client configuration.

2. **Token Acquisition** → The app POSTs to `/api/wow/checkmegatoken` with `WOW_DISCORD_CONSENT` to retrieve a short-lived bearer token for authenticated endpoints.

3. **Mega-Item Names Retrieval** → The `Item_And_Pet_Statistics.run` method POSTs to `/api/wow/megaitemnames` using the acquired token and region parameter to populate UI dropdowns with current auction data.

4. **Item Data Lookups** → When users select specific items, AAA calls `get_ilvl_items()` or `get_itemnames()` from [`api_requests.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/api_requests.py), which POST to `/api/wow/itemdata` with filters for item level, class, and subclass.

5. **Discord Alert Generation** → [`mega_alerts.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/mega_alerts.py) constructs Discord embeds containing Saddlebag links generated by `create_saddlebag_link()`, allowing users to click directly to item data pages from notifications.

## Practical Code Examples for Saddlebag Exchange API Integration

### Fetch the Latest Item Names

```python
from utils.api_requests import get_itemnames

# Returns a JSON list of {"itemId": ..., "itemName": ...}

item_names = get_itemnames()
print(f"Fetched {len(item_names)} items from Saddlebag")

```

This function uses `SADDLEBAG_URL` and the consent flag internally, automatically falling back to GitHub-hosted static data if the API is unreachable.

### Resolve Item Base Item Level and Required Level

```python
from utils.api_requests import get_ilvl_items

# Get data for all items with base ilvl ≥ 201

names, ids, base_ilvls, req_lvls = get_ilvl_items(ilvl=201)

item_id = 19019          # Example: "Thunderfury, Blessed Blade of the Windseeker"

print(f"Item {item_id} → ilvl {base_ilvls[item_id]}, req lvl {req_lvls[item_id]}")

```

### Obtain a Mega-Item-Names Token

```python
import requests
from utils.api_requests import WOW_DISCORD_CONSENT

TOKEN_URL = "https://api.saddlebagexchange.com/api/wow/checkmegatoken"
resp = requests.post(TOKEN_URL, json={"discord_consent": WOW_DISCORD_CONSENT})
token = resp.json()["token"]
print(f"Auth token: {token[:8]}…")

```

### Request Region-Specific Mega-Item Names

```python
import requests
from utils.api_requests import WOW_DISCORD_CONSENT

def fetch_mega_names(region="EU"):
    url = "https://api.saddlebagexchange.com/api/wow/megaitemnames"
    payload = {
        "discord_consent": WOW_DISCORD_CONSENT,
        "region": region,
        "discount": 1,          # no discount – raw data

    }
    return requests.post(url, json=payload).json()

eu_items = fetch_mega_names("EU")
print(f"EU mega list contains {len(eu_items)} rows")

```

### Generate User-Visible Saddlebag Links

```python
from utils.helpers import create_saddlebag_link

item_id = 19019
link = create_saddlebag_link(item_id)
print(f"Shareable link → {link}")

# => https://saddlebagexchange.com/wow/item-data/19019

```

### Update Static Fallback Data via CLI

```bash

# From the repository root

python update-static-saddlebag-data.py

# This will refresh:

#   StaticData/item_names.json

#   StaticData/pet_names.json

#   StaticData/bonuses.json

#   StaticData/ilvl_items.json

#   ...etc.

```

## Key Files for Saddlebag Exchange API Integration

| File | Role | Direct link |
|------|------|-------------|
| [`utils/api_requests.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/api_requests.py) | Core request wrapper, constant definitions, fallback logic | [[`utils/api_requests.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/api_requests.py)](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/api_requests.py) |
| [`utils/helpers.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/helpers.py) | Helper to build public Saddlebag URLs for embeds | [[`utils/helpers.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/helpers.py)](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/helpers.py) |
| [`AzerothAuctionAssassin.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/AzerothAuctionAssassin.py) | Main application entry point – token handling, UI wiring, region‑aware mega‑item calls | [[`AzerothAuctionAssassin.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/AzerothAuctionAssassin.py)](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/AzerothAuctionAssassin.py) |
| [`update-static-saddlebag-data.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/update-static-saddlebag-data.py) | CLI utility to refresh static JSON backups used when the API is unreachable | [[`update-static-saddlebag-data.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/update-static-saddlebag-data.py)](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/update-static-saddlebag-data.py) |
| [`node-ui/mega-alerts.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/mega-alerts.js) | Electron front‑end code that builds Discord/Electron messages with Saddlebag links | [[`node-ui/mega-alerts.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/mega-alerts.js)](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/mega-alerts.js) |
| [`mega_alerts.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/mega_alerts.py) | Server‑side alert generation that inserts Saddlebag item‑data links into Discord embeds | [[`mega_alerts.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/mega_alerts.py)](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/mega_alerts.py) |

These files together provide a **complete, testable integration** with the Saddlebag Exchange API, handling authentication, data retrieval, graceful fallback, and user‑friendly link generation for both the GUI and Discord notifications.

## Summary

- **Azeroth Auction Assassin** integrates with the Saddlebag Exchange API through a three-layer architecture comprising HTTP client utilities, token-based authentication, and UI helper functions.
- The **[`utils/api_requests.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/api_requests.py)** module handles all direct API communication, including the required `WOW_DISCORD_CONSENT` flag and automatic fallback to GitHub-hosted static data when the API is unreachable.
- **Authentication** occurs via [`AzerothAuctionAssassin.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/AzerothAuctionAssassin.py), which obtains short-lived tokens from `/api/wow/checkmegatoken` for accessing protected endpoints like `/api/wow/megaitemnames`.
- **User-facing links** are generated through [`utils/helpers.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/helpers.py) using `create_saddlebag_link()`, enabling direct navigation to item data pages from Discord alerts and the Electron UI.
- The **[`update-static-saddlebag-data.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/update-static-saddlebag-data.py)** CLI utility ensures local fallback data remains synchronized with the live API, maintaining application functionality during outages.

## Frequently Asked Questions

### How does AAA authenticate with the Saddlebag Exchange API?

AAA authenticates using a short-lived token system implemented in [`AzerothAuctionAssassin.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/AzerothAuctionAssassin.py). On startup, the application POSTs to `https://api.saddlebagexchange.com/api/wow/checkmegatoken` with the `WOW_DISCORD_CONSENT` payload to retrieve a bearer token. This token must be included in the Authorization header for subsequent requests to protected endpoints like `/api/wow/megaitemnames`, and AAA automatically refreshes the token when authentication errors occur.

### What happens when the Saddlebag Exchange API is unavailable?

When the Saddlebag Exchange API returns errors or timeouts, AAA automatically falls back to static JSON files hosted on GitHub. The [`utils/api_requests.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/utils/api_requests.py) module contains this fallback logic within functions like `get_itemnames()` and `get_ilvl_items()`, which catch request failures and instead retrieve data from `RAW_GITHUB_BACKUP_PATH`. This ensures the UI remains functional and populated with item data even during API outages.

### Which Saddlebag Exchange API endpoints does AAA consume?

AAA consumes several specific endpoints provided by the Saddlebag Exchange API. The authentication endpoint is `/api/wow/checkmegatoken` for obtaining bearer tokens. For data retrieval, AAA uses `/api/wow/megaitemnames` to fetch region-specific auction item lists and `/api/wow/itemdata` to query specific item details filtered by item level, class, and subclass. These endpoints require the `WOW_DISCORD_CONSENT` flag in all request payloads.

### How can developers update the static fallback data for the Saddlebag Exchange API integration?

Developers can synchronize local fallback data with the live Saddlebag Exchange API by running the [`update-static-saddlebag-data.py`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/update-static-saddlebag-data.py) CLI utility from the repository root. This script pulls the latest item names, pet names, bonuses, update timers, and item level data from the API and writes them to the `StaticData/` directory as JSON files. Running this utility ensures that the GitHub-hosted fallback files remain current, providing users with accurate data during API outages.