Companion Player API
Companion read API · companion Discord bot · BenchMark · third-party apps
Online player info for external readers — Discord bots, the website BenchMark Leaderboard, and studio-registered apps. Component-profile pattern 2 / studio registry: app API key + profile components (not one mega blob). Read-only. Backed by the same Online career / Match / Ladder store as Command Deck Career Records — not a second stats system.
Who this is for
Section titled “Who this is for”| Consumer | Role |
|---|---|
| Companion Discord bot | Separate Discord app. Slash commands / embeds for profile, Ladder, career. Read-only. |
| Website BenchMark Leaderboard | Same API; public Ladder + profile pages. |
| Third-party apps / sites | Studio-registered keys. |
Identity
Section titled “Identity”| Concept | Lock |
|---|---|
| Membership ID | EOS PUID |
| Character ID | Online character GUID on that PUID |
| Display name | Online display name |
| Discord user → PUID | Optional when Discord is linked in-game; opaque id only — never AccessToken |
Solo characters never appear. Empty Solo lookups return empty / 404.
X-API-Key required on every call. Optional later: player OAuth Bearer for Friends / Private components. Per-key rate limits; search is stricter.
Components
Section titled “Components”Request with ?components=. Locked components return privacy: locked when the profile is otherwise visible. Reuse career / match locks — do not invent new stats.
| Component | Backed by | Default |
|---|---|---|
Profiles |
PUID, display name, opaque Discord id, clan tag | Public |
Characters |
Name, Order / Faction, level, subclass unlocks | Public |
CharacterEquipment |
Equipped cosmetics only (what other players already see in-world) | Public (lockable) |
Career |
Journey Career totals | Public (lockable) |
CollectionsMastery |
Collections weapon mastery | Public (lockable) |
Triumphs |
Triumph catalog lifetime counts | Public (lockable) |
ModeAggregates |
RAID / Vault / Ladder mode blocks | Public (lockable) |
LadderStanding |
Season Ladder board | Always public when ranked |
MatchHistory / LastMatchRecap |
Match History archive / last frozen recap | Friends (lockable) |
Hard deny
Section titled “Hard deny”Never exposed: bags / Secure Locker; Credits / BTUCOIN / LUMENAR; owned marketplace listings; Case / mystery / OmniVisor clue progress; Trust cases / reports / ghost; chat logs; Solo pool; passwords; Discord AccessTokens; other players’ fireteam Accept / Join settings; any write or mutate endpoint.
Player privacy (Settings → Social)
Section titled “Player privacy (Settings → Social)”Same Options screen as fireteam privacy. Online only. Defaults: Career / Equipment / Collections / Triumphs / Modes = Public; Match History = Friends. Ladder standing stays public when ranked. App-key-only callers see Public; Friends needs player OAuth.
HTTP surface (v1)
Section titled “HTTP surface (v1)”Host is ops. Path shape is the product 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}— static defs so bots render names / icons
Two Discord products
Section titled “Two Discord products”| Invite Discord | Companion Discord bot | |
|---|---|---|
| Discord application | Game client / invite delivery | Separate app |
| Purpose | Link account + deliver invite deep links | /stats, /ladder, profile cards |
| Auth | Discord OAuth → EOS Connect LinkAccount | Companion API key (+ optional player OAuth later) |
| Writes game state | Invite tokens via game server | None |
Linked Discord enables by-discord lookup for the companion bot. That is identity bridge only — not invite authority. Engineering contract: FS-API-*. Programming Bible: ch. 31.
What this is not
Section titled “What this is not”- Not Character I, not live Match Results chrome, not Trust.
- Not a path to expose Case / Pre-CF mystery state.
- Not replacing EOS Friends with Discord friends.
- Not loadout write / item transfer / instance join from the bot.