Skip to content

swgoh

96 endpoints at a glance
MethodPathSummary
GET/abilities/List Abilities
GET/abilities/{ability_id}/Get Ability
GET/characters/List Characters
GET/characters/{base_id}/unlock-requirements/Character Unlock Requirements
GET/characters/{character_id}/Get Character
GET/characters/names/Character Names
GET/conquests/List Conquests
GET/conquests/{conquest_id}/Get Conquest
GET/events/List Events
GET/events/{event_id}/Get Event
GET/events/{event_id}/{instance_id}/Get Event Instance
GET/game-data/{type_}/List Items
GET/game-data/{type_}/{item_id}/Get Item
GET/game-data/types/List Types
GET/gear/List Gear
GET/gear/{gear_id}/Get Gear
GET/guilds/Get Guilds
GET/guilds/{guild_id}/Get Guild
GET/guilds/{guild_id}/engagement/activity/Get Guild Activity
GET/guilds/{guild_id}/engagement/contributions/Get Guild Contributions
GET/guilds/{guild_id}/history/Get Guild History
GET/guilds/{guild_id}/mods/summary/Get Guild Mods Summary
POST/guilds/{guild_id}/refresh-players/Refresh Guild Players
GET/guilds/{guild_id}/scoreboard/Get Guild Scoreboard
GET/guilds/{guild_id}/speed-sweep/Get Guild Speed Sweep
GET/guilds/{guild_id}/team-readiness/Guild Team Readiness Summary
GET/guilds/{guild_id}/team-readiness/{team_id}/Guild Team Readiness Detail
GET/guilds/{guild_id}/territory-battle/Get Guild Territory Battle
GET/guilds/{guild_id}/territory-wars/Get Guild Territory Wars
GET/guilds/{guild_id}/unit-ownership/{base_id}/Guild Unit Ownership
GET/guilds/{guild_id}/unlock-readiness/Guild Unlock Readiness Overview
GET/guilds/{guild_id}/unlock-readiness/{base_id}/Guild Unlock Readiness
GET/guilds/history/counts/Get History Counts
GET/guilds/search/Search Guilds
GET/leaderboards/Get Leaderboard
GET/leaderboards/metrics/List Metrics
GET/leaderboards/recent-unlocks/Recent Unlocks
GET/lightspeed/tokens/List Tokens
GET/lightspeed/tokens/{token_id}/Get Token
GET/me/follows/List Follows
DELETE/me/follows/{player_id}/Unfollow Player
POST/me/follows/{player_id}/Follow Player
GET/me/notifications/List Notifications
POST/me/notifications/seen/Mark Notifications Seen
GET/mods/recommendations/List Recommendations
GET/mods/recommendations/{recommendation_id}/Get Recommendation
GET/players/Get Players
GET/players/{code}/Get Player
GET/players/{player_id}/activity/Get Player Activity
GET/players/{player_id}/arena-defense/Get Player Arena Defense
GET/players/{player_id}/gac/bracket/Get Player Gac Bracket
POST/players/{player_id}/gac/bracket/refresh/Refresh Player Gac Bracket
GET/players/{player_id}/gac/current/Get Player Gac Current
GET/players/{player_id}/gac/opponents/Get Player Gac Opponents
GET/players/{player_id}/gac/seasons-with-brackets/Get Player Gac Seasons With Brackets
GET/players/{player_id}/gac/seasons/Get Player Gac Seasons
GET/players/{player_id}/gac/seasons/{season_id}/timeline/Get Player Gac Season Timeline
GET/players/{player_id}/gac/timeline/Get Player Gac Timeline
GET/players/{player_id}/history/Get Player History
GET/players/{player_id}/mods/summary/Get Player Mods Summary
GET/players/{player_id}/team-readiness/Player Team Readiness
GET/players/{player_id}/titles/Get Player Titles Route
GET/players/{player_id}/units/Get Player Units
GET/players/{player_id}/units/{base_id}/mods/Get Player Unit Mods
GET/players/{player_id}/units/{unit_id}/Get Player Unit
GET/players/{player_id}/unlock-requirements/Player Unlock Requirements Bulk
GET/players/{player_id}/unlock-requirements/{base_id}/Player Unlock Requirements
GET/players/{player_id}/unlock-requirements/{base_id}/materials/Player Unlock Materials
GET/players/compare/{left_id}/{right_id}/titles/Diff Player Titles Route
GET/players/guild/{guild_id}/Get Players From Guild
GET/players/history/counts/Get Player History Counts
GET/raids/List Raids
GET/raids/{raid_id}/Get Raid
GET/skills/List Skills
GET/skills/{skill_id}/Get Skill
GET/task-history/List Task History
GET/task-history/{run_id}/Get Task Run
POST/tasks/backfill/gac-directionBackfill Gac Direction
POST/tasks/backfill/guild-eventsBackfill Guild Events
POST/tasks/backfill/localizationBackfill Localization
POST/tasks/backfill/meta-createdBackfill Meta Created
POST/tasks/scan/guildsScan New Guilds
POST/tasks/update/eventsUpdate Events
POST/tasks/update/game-dataUpdate Game Data
POST/tasks/update/guildsUpdate Guilds
POST/tasks/update/playersUpdate Players
GET/teams/List Teams
POST/teams/Create Team
DELETE/teams/{team_id}/Delete Team
GET/teams/{team_id}/Get Team
PATCH/teams/{team_id}/Update Team
GET/teams/base-ids/List Team Base Ids
GET/territory/battles/List Battles
GET/territory/battles/{battle_id}/Get Battle
GET/units/{unit_id}/Get Unit
GET/units/{unit_id}/materials/Unit Materials

swgoh


Search Guilds

GET
/guilds/search/

Search Comlink for guilds whose name matches name (substring).

Read-only against Comlink — does not persist results into db.guilds.
Public; the actual "add this guild to our store" step is the
drill-in (GET /guilds/{guild_id}/) which upserts on cache miss
and is officer-gated. Non-officers searching can browse results and
drill into already-tracked guilds; untracked guilds 404 for them.

The minimum query length is 2 characters; shorter queries are rejected
with a 400 to avoid hammering Comlink with overly-broad searches.

Parameters

Query Parameters

name*
Type
string
Required
start_index
Type
integer
Default
0
count
Type
integer
Default
20

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get History Counts

GET
/guilds/history/counts/

Return {guild_id: snapshot_count} across db.guilds_history.

Indexed $group aggregation — finishes in milliseconds even as
the history collection grows. Frontend-friendly dict shape so
callers can do counts[guild_id] directly.

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": 0
}

Playground

Samples


Get Guild History

GET
/guilds/{guild_id}/history/

Parameters

Path Parameters

guild_id*
Type
string
Required

Query Parameters

skip
Type
integer
Default
0
limit
days

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Guild

GET
/guilds/{guild_id}/

Resolve a guild by id.

Discovery (cache miss → Comlink) requires role officer or
higher — that's the "add a new guild" gate. Refreshing an
existing guild is open to everyone, whether implicit (the 24h
staleness auto-refresh) or explicit (?refresh=true): Comlink
call frequency per guild stays bounded either way and a fresh
view is the right page-load behavior for any viewer.

Side effect on first-time discovery: schedules a background
refresh of every member's roster. Without it, derived views
(unit ownership, GL counts, team readiness) would show zero
until the daily cron runs. The task is wrapped via
run_and_record so admins can track progress + errors.

Parameters

Path Parameters

guild_id*
Type
string
Required

Query Parameters

refresh
Type
boolean
Default
false

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Refresh Guild Players

POST
/guilds/{guild_id}/refresh-players/

Manually trigger a refresh of every member's roster.

Officer-gated. Returns 202 + a brief acknowledgement; the
actual work runs as a background task (per-member refreshes
take a few seconds each, so a serial sweep across a 50-member
guild is multi-minute — too long to hold the request).

The data layer's max_age_seconds skip threshold (default
6 h) prevents thrashing when officers click the button
repeatedly. Track progress in /admin/tasks.

Parameters

Path Parameters

guild_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Get Guilds

GET
/guilds/

Responses

Successful Response

application/json
JSON
[
]

Playground

Samples


Get Guild Mods Summary

GET
/guilds/{guild_id}/mods/summary/

Guild-wide mod headline: ML+15 totals, speed-mod totals, per-member rows.

Aggregates every member's parsed mods into a single rollup
suitable for the GuildDetail / GuildStatistics surfaces. Each
member row carries their total_speed / ml15_count / gold_count /
speed_arrow_count so the UI can render a leaderboard inline.

Public — same as the other guild rollups.

Parameters

Path Parameters

guild_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Guild Scoreboard

GET
/guilds/{guild_id}/scoreboard/

Per-member officer triage scoreboard (Theme E).

Combined ranked roster for "who's pulling weight" / "who needs
coaching" / "who would we recruit out". Returns:

  • members — per-member row with GP, league/division/skill,
    activity, roster depth, mod-farming progress
  • medians and percentiles (p25/p75) for each ranked metric
  • coaching_highlights — pre-sorted list of (member, metric)
    pairs below the guild's p25, capped at 30 for readability

Officer-gated — the audit framed this surface as "officer
triage". Per-member raw data is otherwise available via the
individual player pages; the value-add here is the cross-member
ranking + coaching pass.

Parameters

Path Parameters

guild_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Guild Territory Battle

GET
/guilds/{guild_id}/territory-battle/

Per-member breakdown of the guild's most recent Territory Battle.

Read straight from the cached guild envelope — Comlink ships
recentTerritoryBattleResult on every include_activity=True
fetch, so this costs one Mongo read and no upstream call.

Open like the rest of the guild read surface: it is aggregate
participation over data the game shows every member of that guild
anyway, and it carries no roster detail the guild page doesn't.

null result when the guild has no finished TB in its cached
envelope, which is normal between battles rather than an error —
hence 200 with an empty body rather than a 404.

The scoring rule is deliberately narrow; see
:mod:app.swgoh.guild_territory_battle for why summing every
playerStat.score inflates the total ~5x AND reorders the
leaderboard.

Parameters

Path Parameters

guild_id*
Type
string
Required

Query Parameters

instance_id

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Guild Territory Wars

GET
/guilds/{guild_id}/territory-wars/

Every Territory War we have ever captured for this guild.

Comlink only ever shows the last eight; this is the archive built from
every observation since capture began, so it grows past that window
instead of rolling over.

Parameters

Path Parameters

guild_id*
Type
string
Required

Query Parameters

limit
Type
integer
Default
100

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Guild Activity

GET
/guilds/{guild_id}/engagement/activity/

Activity heatmap + AFK roll-up for a guild.

Reads member[].lastActivityTime from the cached guild doc —
no new Comlink calls, no schema-specific parsing (the field has
been there since the project's first ingest). Returns per-member
rows sorted newest-active first, bucket counts (today / 1-3d /
4-7d / 8-14d / 15-29d / 30+d), and a top-level afk_count
using a 7-day threshold.

Public — same gating as the other guild rollups. The info is no
more sensitive than what the per-player lastActivityTime
already exposes individually.

Parameters

Path Parameters

guild_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Guild Contributions

GET
/guilds/{guild_id}/engagement/contributions/

Raid + daily-activity + ticket contribution rollup.

Derived from each member's memberContribution[] array (now
preserved after the Theme C un-pop). The parser classifies each
entry into a normalised bucket (raid / territory / daily_activity
/ guild_currency / ticket / challenge / other) via keyword
matching on the contribution type id — see
:data:app.swgoh.guild_engagement._BUCKET_KEYWORDS for the
rules.

Returns totals per bucket, the per-member parsed rows, plus
pre-sorted raid_leaderboard / ticket_leaderboard /
territory_leaderboard slices (top 50 each) so the UI can
render leaderboard tables without re-sorting.

Public — same policy as the activity endpoint.

Parameters

Path Parameters

guild_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Guild Speed Sweep

GET
/guilds/{guild_id}/speed-sweep/

Every member's speed on one specific unit, sorted desc.

Requires login (any role) per the design decision — speed-sweep
is an arena-scouting tool useful enough that anonymous users can
pick it up off a Google scrape; logged-in friction is the right
compromise. Per-player mod data is otherwise public, so the gate
is UX-level, not a hard privacy line.

Returns rows sorted by total_speed desc. Members missing the
unit drop out (the question is "who has the fastest X", not "who
needs to farm X").

Parameters

Path Parameters

guild_id*
Type
string
Required

Query Parameters

base_id*
Type
string
Required
min_speed
Type
integer
Default
0

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Players From Guild

GET
/players/guild/{guild_id}/

Parameters

Path Parameters

guild_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player History Counts

GET
/players/history/counts/

Return {player_id: snapshot_count} across db.players_history.

Indexed $group aggregation — bounded by index size, finishes in
milliseconds even as the history collection grows. Frontend-friendly
dict shape so the player picker can do counts[player_id] lookups.

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": 0
}

Playground

Samples


Get Player History

GET
/players/{player_id}/history/

Return per-player slim headline snapshots, newest first.

See :meth:Players.get_player_history for the schema and write
semantics. Sync handler — only Mongo I/O, but matches the broader
pattern of using sync routes for blocking work so anyio can
thread-pool the call.

Parameters

Path Parameters

player_id*
Type
string
Required

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
100

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Activity

GET
/players/{player_id}/activity/

Return narrative events for a player, newest first.

types is an optional CSV filter (e.g. unit_geared,unit_relic_promoted)
— unknown types are dropped silently rather than rejected. Empty
or missing types returns all event types.
See :meth:Players.get_player_activity for the row shape.

Parameters

Path Parameters

player_id*
Type
string
Required

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
100
types

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Gac Seasons

GET
/players/{player_id}/gac/seasons/

Per-season GAC summaries for the Season History card.

Public — same gating as /history/ and /activity/. Returns
a paginated list of {season_id, league_id, division_id, rank, points, wins, losses, join_time, end_time}. Sorted newest-first
by join_time so the most recent season is row zero.

Empty list if the player isn't tracked yet, or hasn't been
refreshed since the Phase 1 ingest helpers landed — the upsert
runs on the next get_player call, so a quick refresh fills
the collection.

Parameters

Path Parameters

player_id*
Type
string
Required

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
30

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Gac Current

GET
/players/{player_id}/gac/current/

Live snapshot of the player's current GAC season.

Read straight from the cached db.players envelope — no
Comlink call. Useful for the PlayerGac header (league/division/
skill-rating pill, current W-L, points) without a separate
request to the full player endpoint. 404 if the player isn't
tracked at all.

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Gac Bracket

GET
/players/{player_id}/gac/bracket/

Latest captured GAC bracket for a player, plus per-row diffs.

Reads the most recent db.gac_brackets snapshot and diffs it
against the previous same-season snapshot — each row in the
returned players array carries points_delta and
rank_delta (positive rank_delta = climbed; smaller rank
numbers are better).

Public — same gating as /gac/seasons/ and /gac/current/.
The bracket itself doesn't expose anything more sensitive than
the per-player headline (opponent names + bracket points), and
the cadence is already bounded by the scheduled capture's TTL.

Returns 404 when no bracket has ever been captured for this
player. That's distinct from "captured but empty" — an empty
players array would surface on a snapshot CG returned with
no entries (rare, mid-season-end edge case).

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Refresh Player Gac Bracket

POST
/players/{player_id}/gac/bracket/refresh/

Manually capture this player's current GAC bracket.

Officer-gated. Honors the per-player 5h TTL inside
:meth:Gac.capture_player_bracket — clicking twice in quick
succession is a safe no-op. Wrapped via run_and_record so
the click shows up in the admin task-history view.

Returns the capture result envelope (status / season_id /
observed_at / reason) verbatim so the UI can decide whether to
show "captured" toast vs "TTL — try again later" hint.

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Gac Timeline

GET
/players/{player_id}/gac/timeline/

Most-recent-season snapshot timeline.

Convenience shortcut for the default PlayerGac view — saves a
round-trip discovering the latest season id. Returns the same
envelope as the explicit /timeline/{season_id}/ route.

404 when the player has zero bracket captures (i.e. Phase 2 hasn't
ingested anything for them yet).

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Gac Season Timeline

GET
/players/{player_id}/gac/seasons/{season_id}/timeline/

Snapshot timeline for one specific captured season.

Drives the per-season tab in the PlayerGac timeline UI. Returns
every snapshot for the (player, season) pair, each carrying the
self deltas + the bracket "top gainer" for the interval ending
at that snapshot.

404 if the (player, season) pair has no captures.

Parameters

Path Parameters

player_id*
Type
string
Required
season_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Gac Seasons With Brackets

GET
/players/{player_id}/gac/seasons-with-brackets/

Distinct seasons we have at least one bracket snapshot for.

Powers the season picker in the timeline UI. Returns a flat list
of season_id strings — newest-first ordering is left to the
client because season_id has no canonical lex order (CG embeds
the season number inside a longer template id).

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Gac Opponents

GET
/players/{player_id}/gac/opponents/

Head-to-head roll-up — recurring bracket-mates across all seasons.

Each row carries appearances (total snapshots this opponent
has appeared in our brackets), season_count /
most_recent_season, and the opponent's most-recently-observed
name + guild_name so renames / guild transfers don't
desync the H2H card.

Frequency-only — we don't claim wins/losses here because per-round
opponent identification isn't reliable yet (see the Phase 3
scope notes in app/swgoh/gac.py).

Parameters

Path Parameters

player_id*
Type
string
Required

Query Parameters

limit
Type
integer
Default
30

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Units

GET
/players/{player_id}/units/

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Titles Route

GET
/players/{player_id}/titles/

Player title achievements (Theme G).

Resolves the cached unlockedPlayerTitle[] + selectedPlayerTitle
fields against the title catalog (db.player_title). Returns
the full unlocked list with friendly names + descriptions, plus
the currently-displayed title for the player.

Public — same gating as the other per-player reads. No Comlink
call; pure derivation over the cached envelope.

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Diff Player Titles Route

GET
/players/compare/{left_id}/{right_id}/titles/

Title comparison between two players for PlayerCompare.

Returns left-only / right-only / shared lists (each with friendly
title names) plus per-side and shared counts. Useful as a
"completionism" diff — see exactly what titles one player has
that the other doesn't.

Parameters

Path Parameters

left_id*
Type
string
Required
right_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Arena Defense

GET
/players/{player_id}/arena-defense/

Squad + fleet arena defensive lineups for a player.

Returns {squad: {rank, lineup}, fleet: {rank, lineup}} where
lineup is an ordered list of base_ids (leader first for squad,
capital ship first for fleet). Empty lineup arrays mean the
player hasn't placed a defense or the cached envelope predates
the field — UI renders that as "no defense placed".

Read straight from the cached db.players envelope — no Comlink
call. Public, same gating as the rest of the per-player reads.

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Unit

GET
/players/{player_id}/units/{unit_id}/

Parameters

Path Parameters

player_id*
Type
string
Required
unit_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Mods Summary

GET
/players/{player_id}/mods/summary/

Whole-roster mod analytics: headline counts + top fastest + breakdowns.

Walks every unit envelope in db.units for this player, parses
each unit's equippedStatMod[] against the db.stat_mods
template cache, and rolls up to:

  • headline — speed_mod_count, gold_count, ml15_count, six_pip_count,
    speed_arrow_count, total_roster_speed, fastest_unit
  • all_units — full sortable list of every modded unit, with
    per-unit total_speed / ml15_count / has_speed_arrow etc.
  • slot_distribution — per-slot count + avg speed
  • set_distribution — per-set equipped count

Public — same gating as the rest of the per-player read paths. No
new Comlink calls; all derivation is over the cached unit
envelopes we already store.

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player Unit Mods

GET
/players/{player_id}/units/{base_id}/mods/

Per-unit mod detail: the 6 mods + their per-mod quality / speed.

Used by the per-unit drawer in PlayerMods and as the data source
for an inline mod display on UnitDetail. Returns the parsed mods

  • a per-unit summary so callers don't have to re-compute.

404 if the player doesn't own the unit. Returns an empty mods
list (not a 404) when they own it but haven't equipped any —
that's "they own a freshly-unlocked unit", not an error state.

Parameters

Path Parameters

player_id*
Type
string
Required
base_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Player

GET
/players/{code}/

Resolve a player by ally code or player_id.

Discovery (cache miss → Comlink) requires role officer or
higher — that's the "add a new player" gate. Refreshing an
existing player is open to everyone, whether implicit (the
~28h staleness auto-refresh) or explicit (?refresh=true):
Comlink call frequency per player stays bounded either way and
a fresh view is the right page-load behavior for any viewer.

Parameters

Path Parameters

code*
Type
string
Required

Query Parameters

refresh
Type
boolean
Default
false

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Get Players

GET
/players/

Return a slim projection of every tracked player.

Intentionally omits roster, stats, and profileStat[] — only the fields
a list view needs are projected server-side. See
:meth:Players.get_players for the projection details.

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Samples


Update Game Data

POST
/tasks/update/game-data

Refresh game data from Comlink into MongoDB.

Optional segment (0–4) restricts the refresh to a single
getGameData segment. Segment 0 contains keys that aren't returned
by 1–4 (notably unitGuideDefinition). Optional key further
restricts it to a single Comlink type within that segment
(e.g. key=units).

refresh_loc (default True) folds the localization bundle fetch
into the same run so each item's data.localized.* is stamped at
write time. Pass refresh_loc=false when you only want to refresh a
specific segment without re-fetching the (large) localization payload.

Returns 502 with the upstream message if Comlink is unhealthy (typically
an APK-version mismatch on the Comlink server itself).

Authorizations

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Parameters

Query Parameters

segment
key
refresh_loc
Type
boolean
Default
true

Responses

Successful Response

application/json
JSON
[
]

Playground

Authorization
Variables
Key
Value

Samples


Backfill Meta Created

POST
/tasks/backfill/meta-created

One-shot: stamp meta.created on legacy docs missing it.

Approximates meta.created / meta.created_timestamp from the
existing meta.updated / meta.timestamp values on docs where
meta.created doesn't yet exist. Idempotent — re-running after the
first successful run is a no-op. Optional type_ query param scopes
the backfill to one game-data collection (e.g. ?type_=characters);
omitted, runs across every game-data collection.

Authorizations

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Parameters

Query Parameters

type_

Responses

Successful Response

application/json
JSON
[
]

Playground

Authorization
Variables
Key
Value

Samples


Update Guilds

POST
/tasks/update/guilds

Force-refresh every guild known to db.guilds from Comlink.

Iterates every doc in db.guilds and calls
:meth:Guilds.get_guild with force=True per guild_id, bypassing
the staleness gate. One guild's failure doesn't abort the run.
Returns per-guild outcome counts plus a capped error list.

This is the same path the scheduled refresh_guilds job runs —
handy for manual triggers or verifying the bulk path before the
schedule fires.

Authorizations

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Responses

Successful Response

application/json
JSON
[
]

Playground

Authorization

Samples


Update Players

POST
/tasks/update/players

Force-refresh every player known via any guild in db.guilds.

Walks every guild doc, collects unique guild.member[].playerId
values, then calls :meth:Players.get_player with refresh=True
per id. One player's failure doesn't abort the run. Returns per-player
outcome counts plus a capped error list.

This is the same path the scheduled refresh_players job runs.
Players that exist in db.players but aren't currently in any
tracked guild are not refreshed by this endpoint — by design.

Authorizations

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Responses

Successful Response

application/json
JSON
[
]

Playground

Authorization

Samples


Scan New Guilds

POST
/tasks/scan/guilds

Discover guilds we don't track yet by scanning db.players.

Walks every player record, finds player.guildId values we don't
already have in db.guilds, fetches each via
:meth:Guilds.get_guild, and pulls any newly seen guild's members
into db.players.

Same path the scheduled scan_new_guilds job runs. Returns
{candidates, new_guilds, added_players, errors}.

Authorizations

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Responses

Successful Response

application/json
JSON
[
]

Playground

Authorization

Samples


Update Events

POST
/tasks/update/events

Refresh live events from Comlink /getEvents into db.events.

Each event is flattened into one Mongo doc per (event, instance)
pair so time-window queries (active / upcoming / past) hit
indexed range filters directly.

refresh_loc (default True) also refreshes the localization
bundle so event.localized.* is stamped against the latest
translations. Pass false to use whatever's currently in
db.localization and skip the loc fetch.

Authorizations

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Parameters

Query Parameters

refresh_loc
Type
boolean
Default
true

Responses

Successful Response

application/json
JSON
[
]

Playground

Authorization
Variables
Key
Value

Samples


Backfill Guild Events

POST
/tasks/backfill/guild-events

One-shot: recover finished TB / TW results from stored snapshots.

Comlink's guild envelope only carries the last one Territory Battle
and the last eight wars, but Guilds._save_history has been
snapshotting whole envelopes for as long as guilds have been tracked —
so older events are still on disk, buried in ~648 KB rows nothing read.
This walks them into db.guild_tb_results / db.guild_tw_results.

Nothing is invented: a row appears only if some snapshot actually
observed that event. Idempotent, so re-running reports zeros rather
than duplicating, and it is safe to run while the daily refresh is
going.

Authorizations

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Parameters

Query Parameters

guild_id

Responses

Successful Response

application/json
JSON
[
]

Playground

Authorization
Variables
Key
Value

Samples


Backfill Gac Direction

POST
/tasks/backfill/gac-direction

One-shot: repair GAC promotion/demotion events stored inverted.

Division 5 is the top of a league, not Division 1, so every
gac_promoted / gac_demoted row written before that was fixed
says the opposite of what happened.

Dry run by default — this rewrites history, so apply=false
returns the counts without touching anything. Pass apply=true to
write.

The direction is recomputed from each row's own details rather than
the type being flipped: a league change was already correct (the league
dominates), and a blind flip would corrupt those. That also makes it
idempotent.

Authorizations

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Parameters

Query Parameters

apply
Type
boolean
Default
false
player_id

Responses

Successful Response

application/json
JSON
[
]

Playground

Authorization
Variables
Key
Value

Samples


Backfill Localization

POST
/tasks/backfill/localization

One-shot: stamp data.localized.* on existing game-data docs.

Refreshes the localization bundle and walks every game-data collection
(or just type_), resolving data.{nameKey,descKey,descriptionKey}
into data.localized.{name,desc,description} for each doc that has
at least one resolvable key. Idempotent — re-running rewrites the same
fields from scratch, no duplication.

Authorizations

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Parameters

Query Parameters

type_

Responses

Successful Response

application/json
JSON
[
]

Playground

Authorization
Variables
Key
Value

Samples


Get Unit

GET
/units/{unit_id}/

Parameters

Path Parameters

unit_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Unit Materials

GET
/units/{unit_id}/materials/

Step-by-step gear + relic cost to take this unit to max.

One entry per remaining upgrade — finishing the gear ladder, then
each outstanding relic tier — plus a combined total. Costs are
baselined from what the unit has now, including partially-filled
gear slots.

Totals are gross: Comlink exposes no player inventory, so this is
what the unit requires, not what's left after what the player
already holds.

Parameters

Path Parameters

unit_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Characters

GET
/characters/

List characters.

By default returns one row per playable unit — canonical=true
collapses the raw Comlink rows (which emit one row per rarity tier and
several non-playable variants like PVE_*, _GL_EVENT,
_GLE_INHERIT, _TRANSFORMED) down to the maxRarity row of each
playable unit. Pass canonical=false to see every Comlink row
unfiltered.

gl=true returns only Galactic Legends (data.legend == true from
Comlink), gl=false returns only non-GLs, omitting the param applies
no GL filter. Combines with canonical: ?gl=true alone gives
every GL variant, ?gl=true&canonical=true (the default) gives one
row per playable GL.

ships=true returns only ships, ships=false returns only
characters (i.e. non-ships), omitting the param returns both. Comlink
lumps both unit kinds into the same units segment, hence both end
up in this collection; the filter keys off data.combatType
(string "CHARACTER" or "SHIP").

Parameters

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200
name
gl
ships
canonical
Type
boolean
Default
true

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Character Names

GET
/characters/names/

{baseId: display name} for every playable character.

A slim companion to GET /characters/ for the common case of
"turn a base_id into a name". The full catalog is ~16 MB because
each record carries its whole gear/skill/stat tree; this is ~20 KB.
Use it for any name lookup, and reserve the full endpoint for
callers that actually read the other fields (the unit catalog and
picker filter on combatType / obtainable, for example).

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Samples


Get Character

GET
/characters/{character_id}/

Parameters

Path Parameters

character_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Gear

GET
/gear/

Parameters

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200
name

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Gear

GET
/gear/{gear_id}/

Parameters

Path Parameters

gear_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Types

GET
/game-data/types/

List the game-data collections currently present in Mongo.

Responses

Successful Response

application/json
JSON
[
  
"string"
]

Playground

Samples


List Items

GET
/game-data/{type_}/

List items of one type. Supports skip, limit, and name regex.

Parameters

Path Parameters

type_*
Type
string
Required

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200
name

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Item

GET
/game-data/{type_}/{item_id}/

Fetch a single item from db[type_] by its Comlink id.

Parameters

Path Parameters

type_*
Type
string
Required
item_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Recommendations

GET
/mods/recommendations/

List documents from db.mod_recommendation.

Parameters

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Recommendation

GET
/mods/recommendations/{recommendation_id}/

Fetch a single mod-recommendation doc by its _id.

Parameters

Path Parameters

recommendation_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Abilities

GET
/abilities/

Parameters

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200
name

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Ability

GET
/abilities/{ability_id}/

Parameters

Path Parameters

ability_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Skills

GET
/skills/

Parameters

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200
name

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Skill

GET
/skills/{skill_id}/

Parameters

Path Parameters

skill_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Tokens

GET
/lightspeed/tokens/

List documents from db.lightspeed_token.

Parameters

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200
name

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Token

GET
/lightspeed/tokens/{token_id}/

Fetch a single Lightspeed Token by its Comlink id.

Parameters

Path Parameters

token_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Conquests

GET
/conquests/

List documents from db.conquests.

Parameters

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200
name

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Conquest

GET
/conquests/{conquest_id}/

Fetch a single conquest definition by its Comlink id.

Parameters

Path Parameters

conquest_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Raids

GET
/raids/

List documents from db.guild_raids.

Parameters

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200
name

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Raid

GET
/raids/{raid_id}/

Fetch a single guild-raid definition by its Comlink id.

Parameters

Path Parameters

raid_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Battles

GET
/territory/battles/

List documents from db.territory_battles.

Parameters

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
200
name

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Battle

GET
/territory/battles/{battle_id}/

Fetch a single territory-battle definition by its Comlink id.

Parameters

Path Parameters

battle_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Events

GET
/events/

List event instances.

status filters by current time-window: active (running now),
upcoming (starts later), past (already ended). Anything else
(including omitting it) returns the whole collection. type filters
on Comlink's readable enum string for event.type — e.g.
DOUBLE_DROP, CONQUEST, SHIP_EVENT — pass the value as-is.

Sorted most-recent-first by start_time_ms.

Parameters

Query Parameters

status
type
skip
Type
integer
Default
0
limit
Type
integer
Default
200

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Event

GET
/events/{event_id}/

Return the most-recent instance for event_id.

Many events recur (e.g. shipevent_PRELUDE_ACKBAR runs continuously);
this endpoint surfaces the latest occurrence as a single doc. To get a
specific historical instance use the /{event_id}/{instance_id}/ form
or the list endpoint with appropriate filters.

Parameters

Path Parameters

event_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Get Event Instance

GET
/events/{event_id}/{instance_id}/

Return one exact (event, instance) occurrence by composite key.

Parameters

Path Parameters

event_id*
Type
string
Required
instance_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Task History

GET
/task-history/

List task-run summaries, most-recent first.

Optional filters:

  • task_name — exact match (e.g. refresh_guilds,
    refresh_game_data, scan_new_guilds, …).
  • statussuccess or failed.
  • triggerscheduled or manual.

limit is clamped to 1000 to keep responses bounded.

Parameters

Query Parameters

task_name
status
trigger
skip
Type
integer
Default
0
limit
Type
integer
Default
100

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Get Task Run

GET
/task-history/{run_id}/

Fetch a single task-run summary by its _id.

The id is the stringified ObjectId returned in the list endpoint.

Parameters

Path Parameters

run_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


List Team Base Ids

GET
/teams/base-ids/

Flat deduplicated list of every base_id used by any team slot.

Drives the PlayerCompare "key units" head-to-head — units that
show up in at least one defined team are GAC-relevant by
definition (officers curate by editing teams). Sorted
alphabetically so the response is stable across calls.

Public — same policy as the rest of the team-list reads.

Responses

Successful Response

application/json
JSON
[
  
"string"
]

Playground

Samples


List Teams

GET
/teams/

List all teams, optionally filtered. Newest first.

Public — same policy as the team-readiness rollups that read
from this list. Create / update / delete remain officer-gated.

Parameters

Query Parameters

category
combat_type

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Variables
Key
Value

Samples


Create Team

POST
/teams/

Parameters

Request Body

application/json
JSON
{
  
"name": "string",
  
"description": "string",
  
"categories": [
  
  
"string"
  
],
  
"combat_type": "character",
  
"lineup_size": 5,
  
"members": [
  
  
{
  
  
  
"base_id": "string",
  
  
  
"required": true,
  
  
  
"min_relic": 0,
  
  
  
"min_zetas": 0,
  
  
  
"min_omicrons": 0,
  
  
  
"required_skills": [
  
  
  
  
{
  
  
  
  
  
"skill_id": "string",
  
  
  
  
  
"kind": "string"
  
  
  
  
}
  
  
  
]
  
  
}
  
]
}

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Body

Samples


Get Team

GET
/teams/{team_id}/

Single-team detail. Public — the list endpoint already returns
the same public_team shape for every team, so gating just one
of them would be inconsistent. Edit / delete remain officer-gated.

Parameters

Path Parameters

team_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Delete Team

DELETE
/teams/{team_id}/

Parameters

Path Parameters

team_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Update Team

PATCH
/teams/{team_id}/

Partial update.

Only fields explicitly present in the request body are touched.
Required-non-null fields (name / combat_type / members)
silently drop an explicit null rather than corrupting the doc;
nullable fields (description / category) honor the clear.

Parameters

Path Parameters

team_id*
Type
string
Required

Request Body

application/json
JSON
{
  
"name": "string",
  
"description": "string",
  
"categories": [
  
  
"string"
  
],
  
"combat_type": "string",
  
"lineup_size": 0,
  
"members": [
  
  
{
  
  
  
"base_id": "string",
  
  
  
"required": true,
  
  
  
"min_relic": 0,
  
  
  
"min_zetas": 0,
  
  
  
"min_omicrons": 0,
  
  
  
"required_skills": [
  
  
  
  
{
  
  
  
  
  
"skill_id": "string",
  
  
  
  
  
"kind": "string"
  
  
  
  
}
  
  
  
]
  
  
}
  
]
}

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value
Body

Samples


Guild Team Readiness Summary

GET
/guilds/{guild_id}/team-readiness/

Per-team bucket distributions across the whole guild.

One row per team. The frontend either renders the granular
buckets directly (twelve-bar histogram) or rolls them up into
the four-headline summary for the overview list.

Public — same policy as /guilds/{id}/unlock-readiness/. Team
creation/edit/delete remains officer-gated; the list is just a
derived rollup over public roster data.

Parameters

Path Parameters

guild_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Guild Team Readiness Detail

GET
/guilds/{guild_id}/team-readiness/{team_id}/

Per-member breakdown of a single team across the guild.

Returns one entry per guild member with that player's tier, the
weakest-link descriptor (when one exists), and a parallel-to-the-
team-roster array of slim per-slot details so the detail table
can colour each cell by individual unit tier.

Parameters

Path Parameters

guild_id*
Type
string
Required
team_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Player Team Readiness

GET
/players/{player_id}/team-readiness/

Every defined team scored against one player's roster.

Sorted server-side by best-tier-first so the player (or anyone
looking at them) sees "what they're ready for" before "what
they're missing". Ties broken by team name for stability.

Public — same policy as /players/{id}/unlock-requirements/;
surfacing one player's readiness against the team list doesn't
expose anything an officer-only roster view would have hidden.

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Guild Unit Ownership

GET
/guilds/{guild_id}/unit-ownership/{base_id}/

Per-character ownership snapshot across one guild.

Walks each member's unit doc for base_id and buckets them on
the same granular tier ladder team-readiness uses (missing /
unlocked / g13 / r1r9). Returns the headline
ownership numbers + the bucket histogram + the coarse 4-headline
summary the frontend uses to render the "Your guild" card on
CharacterDetail.

Public — same policy as the per-character unlock endpoints. The
data is derived from public roster info; we don't expose
anything /players/{id}/ doesn't already.

Parameters

Path Parameters

guild_id*
Type
string
Required
base_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Character Unlock Requirements

GET
/characters/{base_id}/unlock-requirements/

Catalog view: what does it take to unlock this unit?

404 when the unit has no guide entry at all (most non-event
characters — they're farmable, no unlock requirements). Returns
has_data=False for units that have a guide entry but where
we couldn't resolve a per-character requirement list (older
Legendary events that gate by category rather than named units).

Parameters

Path Parameters

base_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Player Unlock Requirements Bulk

GET
/players/{player_id}/unlock-requirements/

Bulk: every gated character scored against the player's roster.

With ?gl=true the response is restricted to Galactic Legends
(the highest-interest unlocks); with ?gl=false to non-GLs;
omitted returns both. Default is "everything we have a guide for"
so the front-end can decide what to filter client-side.

Public — same as the per-character variant. Officers don't get
additional info here.

Parameters

Path Parameters

player_id*
Type
string
Required

Query Parameters

gl

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Player Unlock Requirements

GET
/players/{player_id}/unlock-requirements/{base_id}/

Player-scored view: catalog + this player's progress overlay.

Same 404 semantics as the catalog endpoint. When the player owns
no units at all (unknown player_id) the response still returns
has_data from the catalog and per-task met=False rather
than 404 — there's nothing player-specific that's missing, just
everything-is-zero.

Parameters

Path Parameters

player_id*
Type
string
Required
base_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Player Unlock Materials

GET
/players/{player_id}/unlock-requirements/{base_id}/materials/

Total gear + relic materials still needed for this unlock.

Sums, across every required character the player hasn't yet brought
to its threshold, the gear salvage / relic materials / credits
needed to close the gap — baselined from what each character has
now, including partially-filled gear slots.

Kept separate from the scored endpoint above because it walks the
recipe tree across three collections; that endpoint is consumed by
several list views and shouldn't pay this cost. Fetch this one
lazily when the panel is opened.

Note the totals are gross: Comlink exposes no player inventory, so
this is what the characters require, not what's left after what the
player already holds. The response says so in caveats.

Parameters

Path Parameters

player_id*
Type
string
Required
base_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Guild Unlock Readiness Overview

GET
/guilds/{guild_id}/unlock-readiness/

Public guild overview: every gated character with guild-wide aggregates.

For each unlockable character (filterable to GLs / non-GLs), counts
members in five buckets: already_unlocked, ready (all prereqs met
but not unlocked), near (within 2 prereqs), in_progress (any
progress), locked_away (no progress at all). Plus the top-3
closest members per character so the row preview tells the leader
"push these three" without a click.

Sort: members_near_unlock desc, then members_unlocked desc,
then alphabetical. Surfaces "where farm pushes pay off most" first.

Parameters

Path Parameters

guild_id*
Type
string
Required

Query Parameters

gl

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Guild Unlock Readiness

GET
/guilds/{guild_id}/unlock-readiness/{base_id}/

Public guild rollup: every guild member ranked against one gated unit.

Useful for "who in the guild is closest to unlocking GL Luke?" and
for prioritising farm assignments. Each row carries the same per-
player summary the bulk player endpoint produces (overall_met,
overall_total, already_unlocked, phases). Members not in the
units collection at all are still listed with everything zeroed
so the leader sees "we don't have roster data for X" instead of
silently dropping them.

Parameters

Path Parameters

guild_id*
Type
string
Required
base_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground

Variables
Key
Value

Samples


Get Leaderboard

GET
/leaderboards/

Ranked top-N tracked players by one headline metric.

metric must be one of the keys in
:data:app.swgoh.leaderboards.RANKED_METRICS; unrecognised
metric strings 400. limit is clamped to [1, 500].

guild_id (optional) scopes the ranking to a single guild's
current roster — the "see only one guild" filter. When the
guild isn't tracked the response carries guild_not_tracked: true with an empty rows so the UI can show a hint.

Each row carries the ranked metric value + a small set of side
metrics (GP / skill_rating / R7+ count / etc.) so the UI can
render context columns without re-fetching per player.

Parameters

Query Parameters

metric
Type
string
Default
"gp_total"
limit
Type
integer
Default
100
guild_id

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


List Metrics

GET
/leaderboards/metrics/

List the whitelisted ranked metrics.

Drives the metric picker on the leaderboards view so the frontend
doesn't keep a parallel table — adding a new metric is one entry
in the backend whitelist and the picker picks it up automatically.

Responses

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground

Samples


Recent Unlocks

GET
/leaderboards/recent-unlocks/

Cross-player unit_acquired event feed, newest first.

guild_id (optional) scopes the feed to that guild's current
members — pairs with the leaderboard's guild filter so both
panels move together. Capped at 500. Each row carries identity +
the unit's base_id + rarity / gear / relic_display at acquisition
time. The frontend renders these with localized unit names via
its existing catalog.

Parameters

Query Parameters

limit
Type
integer
Default
100
guild_id

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


List Notifications

GET
/me/notifications/

Per-user notification feed.

Aggregates db.player_events for the logged-in user's own
player_id plus their followed players, filtered to the
notifiable event types. Returns recent events + total unread
count (events newer than notifications_seen_at).

Parameters

Query Parameters

limit
Type
integer
Default
50

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Mark Notifications Seen

POST
/me/notifications/seen/

Mark all notifications as seen up to now.

Stamps users.preferences.notifications_seen_at to the current
epoch second. Subsequent list_notifications calls compute
unread_count against this watermark.

Parameters

Responses

Successful Response

application/json
JSON
[
]

Playground

Samples


List Follows

GET
/me/follows/

Return the followed-player list with names + guild context.

Parameters

Responses

Successful Response

application/json
JSON
[
]

Playground

Samples


Follow Player

POST
/me/follows/{player_id}/

Add player_id to the user's followed list. Idempotent.

Capped at 50 follows per user — the cap is enforced server-side
in :func:app.swgoh.notifications.follow and silently drops
the 51st request to keep the panel snappy.

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


Unfollow Player

DELETE
/me/follows/{player_id}/

Remove player_id from the user's followed list. Idempotent.

Parameters

Path Parameters

player_id*
Type
string
Required

Responses

Successful Response

application/json
JSON
[
]

Playground

Variables
Key
Value

Samples


SWGoH — Blue Sapphire Software.