egs-api 0.10.2

Interface to the Epic Games API
Documentation

egs-api

Async Rust client for the Epic Games Store API. Handles authentication, asset management, download manifest parsing (binary + JSON), and Fab marketplace integration.

Built on reqwest / tokio.

Features

  • Authentication — OAuth login via authorization code, exchange token, or refresh token. Session resume and invalidation.
  • Assets — List owned assets, fetch catalog metadata (including DLC trees), retrieve asset manifests with CDN download URLs.
  • Download Manifests — Parse Epic's binary and JSON manifest formats. Exposes file lists, chunk hashes, and custom fields needed to reconstruct downloads.
  • Fab Marketplace — List Fab library items, fetch Fab asset manifests with signed distribution points, and download Fab manifests.
  • Account — Account details, bulk account ID lookup, friends list (including pending requests).
  • Entitlements — Query all user entitlements (games, DLC, subscriptions).
  • Library — Paginated library listing with optional metadata.
  • Tokens — Game exchange tokens and per-asset ownership tokens (JWT).
  • Cloud Saves — List, query, and delete cloud save files.
  • Uplay Integration — Query and redeem Ubisoft activation codes via Epic's GraphQL store API.

Quick Start

Add to Cargo.toml:

[dependencies]
egs-api = "0.9"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use egs_api::EpicGames;

#[tokio::main]
async fn main() {
    let mut egs = EpicGames::new();

    // Authenticate with an authorization code obtained from:
    // https://www.epicgames.com/id/api/redirect?clientId=34a02cf8f4414e29b15921876da36f9a&responseType=code
    let code = "your_authorization_code".to_string();
    if egs.auth_code(None, Some(code)).await {
        println!("Logged in as {}", egs.user_details().display_name.unwrap_or_default());
    }

    // List all owned assets
    let assets = egs.list_assets(None, None).await;
    println!("You own {} assets", assets.len());

    // Get detailed info for the first asset
    if let Some(asset) = assets.first() {
        if let Some(info) = egs.asset_info(asset).await {
            println!("{}: {}", info.id, info.title.unwrap_or_default());
        }
    }
}

Authentication Flow

Epic uses OAuth2 with a launcher client ID. The typical flow is:

  1. Open the authorization URL in a browser — the user logs in and is redirected to a JSON page containing an authorizationCode.
  2. Pass that code to egs.auth_code(None, Some(code)).
  3. On success, egs.user_details() contains the session tokens.

To persist the session across runs, serialize egs.user_details() (it implements Serialize / Deserialize) and restore it later with egs.set_user_details(saved) followed by egs.login() which will use the refresh token to re-authenticate.

Authorization URL:

https://www.epicgames.com/id/login?redirectUrl=https%3A%2F%2Fwww.epicgames.com%2Fid%2Fapi%2Fredirect%3FclientId%3D34a02cf8f4414e29b15921876da36f9a%26responseType%3Dcode

See the auth example for a complete interactive flow with token persistence.

Examples

The crate ships with examples covering every endpoint. Run them with:

# First: authenticate and save a token
cargo run --example auth

# Then run any of these (they reuse the saved token):
cargo run --example account              # Account details, ID lookup, friends, external auths, SSO
cargo run --example entitlements         # List all entitlements
cargo run --example library              # Paginated library listing
cargo run --example assets               # Full pipeline: list → info → manifest → download manifest
cargo run --example game_token           # Exchange code + ownership token
cargo run --example fab                  # Fab library → asset manifest → download manifest
cargo run --example catalog              # Catalog items, offers, bulk lookup
cargo run --example commerce             # Currencies, prices, billing, quick purchase
cargo run --example status               # Service status (lightswitch API)
cargo run --example presence             # Update online presence
cargo run --example client_credentials   # App-level auth + library state tokens
cargo run --example cloud_saves          # Cloud save file listing + management
cargo run --example uplay                # Ubisoft activation code queries

API Overview

The public API is the EpicGames struct. It wraps an internal HTTP client with cookie storage and bearer token management. Most methods return Option<T> or Vec<T> (swallowing transport errors); Fab methods return Result<T, EpicAPIError> to expose timeout/error distinctions.

Authentication

Method Description
auth_code(exchange_token, authorization_code) Start a new session
auth_sid(sid) Authenticate via SID cookie (web-based exchange code flow)
auth_client_credentials() App-level auth (no user context)
login() Resume session using saved refresh token
logout() Invalidate current session
is_logged_in() Check if access token is still valid (>600s remaining)
user_details() / set_user_details(data) Get/set session state for persistence

Epic Games Store

Method Description
list_assets(platform, label) List all owned assets (default: Windows/Live)
asset_info(asset) Catalog metadata for an asset (includes DLC list)
asset_manifest(platform, label, namespace, item_id, app) CDN manifest with download URLs
asset_download_manifests(manifest) Parse binary/JSON download manifests from all CDN mirrors
catalog_items(namespace, start, count) Paginated catalog items for a namespace
catalog_offers(namespace, start, count) Paginated catalog offers for a namespace
bulk_catalog_items(items) Bulk fetch catalog items across namespaces
currencies(start, count) Available currencies with symbols and decimals
game_token() Short-lived exchange code for game launches
ownership_token(asset) JWT proving asset ownership
library_state_token_status(token_id) Check library state token validity
artifact_service_ticket(platform, label, namespace, item_id, app) Artifact service download ticket
game_manifest_by_ticket(platform, label, namespace, item_id, app, ticket) Game manifest via artifact service ticket
launcher_manifests(platform, label, namespace, item_id, app) Launcher asset manifests
delta_manifest(manifest, old_build_id, new_build_id) Delta/patch manifest between two builds

Cloud Saves

Method Description
cloud_save_list() List all cloud save files for the current user
cloud_save_query(filename) Query metadata for a specific cloud save file
cloud_save_delete(filename) Delete a cloud save file

Uplay / Store Integration

Method Description
store_get_uplay_codes(namespace, offer_id) Query Ubisoft activation codes for a game
store_claim_uplay_code(namespace, offer_id) Claim a Ubisoft activation code
store_redeem_uplay_codes(uplay_codes) Redeem Ubisoft activation codes

Fab Marketplace

Method Description
fab_library_items(account_id) List all Fab library items (paginated)
fab_asset_manifest(artifact_id, namespace, asset_id, platform) Signed download info with distribution points
fab_download_manifest(download_info, distribution_point_url) Parse download manifest from a specific CDN
fab_file_download_info(listing_id, format_id, file_id) Download info for a specific Fab file

Account & Social

Method Description
account_details() Email, display name, country, 2FA status
account_ids_details(ids) Bulk lookup of account IDs to display names
account_friends(include_pending) Friends list with pending request status
external_auths(account_id) Linked platform accounts (Steam, PSN, Xbox, etc.)
sso_domains() SSO domain list for cookie sharing
user_entitlements() All entitlements (games, DLC, subscriptions)
library_items(include_metadata) Library records with optional metadata

Commerce

Method Description
offer_prices(namespace, offer_ids, country) Offer pricing with formatted strings
quick_purchase(namespace, offer_id) Quick purchase (free game claims)
billing_account() Default billing account and country

Status & Presence

Method Description
service_status(service_id) Service operational status (lightswitch API)
update_presence(session_id, body) Update user online presence

Download Manifest Format

The DownloadManifest struct handles Epic's binary manifest format (with JSON fallback). The binary format is little-endian, optionally zlib-compressed:

Header (41 bytes):
  magic(u32) → header_size(u32) → size_uncompressed(u32) →
  size_compressed(u32) → sha_hash(20 bytes) → compressed(u8) → version(u32)

Body (zlib-compressed):
  Meta:   feature_level, is_file_data, app_id, app_name, build_version, launch_exe, ...
  Chunks: guid(16 bytes) × N, hash(u64) × N, sha(20 bytes) × N, group(u8) × N, ...
  Files:  filename × N, symlink_target × N, sha_hash(20 bytes) × N, install_tags × N, chunk_parts × N
  Custom: key-value pairs (e.g., BaseUrl, CatalogItemId, BuildLabel)

Use DownloadManifest::parse(data) to parse either format. Access file lists via file_manifest_list, chunk info via chunk_hash_list, and custom fields via custom_field(key).

Architecture

EpicGames (public facade, src/lib.rs)
  └── EpicAPI (internal, src/api/mod.rs)
        ├── login.rs    — OAuth: start, resume, invalidate
        ├── egs.rs      — Assets, manifests, library, cloud saves, tokens
        ├── account.rs  — Account details, friends, entitlements
        ├── fab.rs      — Fab marketplace integration
        └── store.rs    — Uplay/Ubisoft code redemption (GraphQL)

EpicGames is the consumer-facing struct. It delegates to EpicAPI which holds the reqwest::Client (with cookie store) and UserData (session state). API methods are split across files via impl EpicAPI blocks.

License

MIT