Skip to content

31 — Companion Player API

Ship a read-only public HTTP API so a separate companion Discord bot, the website BenchMark Leaderboard, and third-party apps can look up Online player info — app-key + component-profile style (app key + profile components). Not a second career store inside UE. Not the invite-delivery Discord app.

Layer Owns
TFAOnline Authoritative Online career / Match History / Ladder writes (FS-MCH / FS-CAR)
Companion API gateway Read HTTP v1 in front of that store + CDN manifest
Invite Discord Client SDK → EOS_Connect_LinkAccount + invite deep links (FS-SOC-004) — different Discord application
Companion Discord bot Separate Discord app; X-API-Key only; slash commands / embeds; no invite Send
MonetaryPlatform AntiCheat Trust / fraud only — not profile stats
Concept Lock
Membership ID EOS PUID
Character ID Online character GUID
Display name Online display name
Discord → PUID GET /memberships/by-discord/{id} when linked (FS-ID-004 C); opaque id only

Solo pool never appears.

  • X-API-Key required on every call (studio-registered, revocable).
  • Optional later: player OAuth Bearer for Friends / Private components.
  • Per-key rate limits; search stricter.

Components (reuse FS §19 — do not invent stats)

Section titled “Components (reuse FS §19 — do not invent stats)”
Component Source Default
Profiles PUID, display name, opaque Discord id, clan tag Public
Characters Name, Order / Faction, level, subclass unlocks Public
CharacterEquipment Equipped cosmetics only (FS-NET-002) Public (lockable)
Career FS-CAR-001 Public (lockable)
CollectionsMastery FS-CAR-002 Public (lockable)
Triumphs FS-CAR-003 Public (lockable)
ModeAggregates FS-CAR-004 Public (lockable)
LadderStanding FS-CAR-005 Public when ranked
MatchHistory / LastMatchRecap FS-MCH-006 / FS-MCH-002 Friends (lockable)

Hard deny: bags / Secure Locker; Credits / BTUCOIN / LUMENAR; marketplace listings; Case / mystery / OV clues; Trust / reports / ghost; chat; Solo; secrets / Discord tokens; others’ fireteam Accept / Join; any write / mutate.

Host is ops. Path shape is the lock:

  • GET /memberships/search?displayname=
  • GET /memberships/by-discord/{discordUserId}
  • GET /profiles/{puid}?components=
  • GET /profiles/{puid}/characters/{characterId}?components=
  • GET /leaderboards/ladder?season=
  • GET /manifest/{entityType}/{hash}

Locked components → privacy: locked (prefer over bare 404 on an otherwise visible profile).

Settings → Social (same Options as fireteam privacy). Defaults: Career / Equipment / Collections / Triumphs / Modes = Public; Match History = Friends. Ladder standing stays public when ranked. App-key-only callers see Public components; Friends needs player OAuth.

  • FS / Architecture / FE design locks (FS-API-*, P9c, profile privacy rows)
  • GDD chapter + this PB chapter + companion map spec
  • Online career / match / Ladder contracts (FS-CAR / FS-MCH) to back the read store
  • Discord Connect link for optional by-discord bridge
  • Companion API gateway service (P9c)
  • CDN / static manifest publish for Orders, Receivers, Triumphs
  • Studio app-key registration + revoke
  • Companion Discord bot application (separate from invite)
  • Optional player OAuth for Match History / Friends visibility
  • AC-API-001 — app-key search + public Characters / Career / Ladder; Match History locked without OAuth under default Friends; hard deny bags / wallets; Discord-id only when linked; companion app ≠ invite Discord
  1. Manifest + Ladder board
  2. Membership search + Characters + Career
  3. Equipment / Collections / Triumphs
  4. Discord-id membership bridge
  5. Match History + player OAuth
  6. Third-party app key portal