Skip to main content

Manual admin sync behavior

Admin sync endpoints expose controlled trigger behavior:
  • /api/admin/teams/sync supports canonical team provisioning semantics
  • /api/admin/leagues/sync triggers leagues data refresh logic
Both routes require privileged authorization and return structured sync summaries.

Webhook-triggered sync behavior

  • /api/webhooks/leagues-sync is triggered by the leagues repository workflow.
  • Requests require valid webhook secret headers.
  • Successful runs update backend league/team data consumed by clients.

API response shapes consumed by clients

  • /api/teams returns enriched team payloads (counts, ranking context, league linkage, never-null sport).
  • GET /api/teams?slug= returns a single team. Archived-team slug checks are case-insensitive.
  • GET /api/teams/{id} is public and resolves id first, then slug. The payload matches a list entry plus teamRecord, foundedDate, and viewerCanPostAsTeam. Archived or unknown teams return 404. A missing id returns 400.
  • Starred HQ teams (/api/me/starred-teams) are bookmarks, not follows. The cap is 50 clubs. PUT is idempotent and returns 409 STARRED_TEAMS_LIMIT for a new id past the cap. POST merges a client snapshot and reports skipped plus rejected instead of failing the batch.
  • GET /api/teams/search filters by q (max 64), sport, league, cursor, limit (1–50), and sort (rank | name | fans).
  • GET /api/config/sports groups leagues by League.sport. There is no second hardcoded catalog.
  • GET /api/user/teams returns { joinedTeamIds, followedTeamIds }.
  • POST/DELETE /api/teams/{id}/join mutates leaderboard membership only and is idempotent. TeamFollow is unchanged.
  • GET /api/teams/{id}/roster is public and returns active Player rows for the lineup builder. Each player may include photo and availability; both are omitted when empty or available.
  • /api/leagues returns league metadata and color/logo payloads.
  • GET /api/teams/{id}/head-to-head?opponentId= is public and returns { record, meetings } for the five most recent decided meetings from the team’s perspective. Missing opponentId or opponentId equal to {id} returns 400.
  • GET /api/teams/{id}/achievements is public and returns the team’s badges.
  • GET /api/leagues/{leagueId}/standings returns { rows, tiebreakRules, tables }. rows is one team each (division, else conference, else league). tables lists every remaining scope. Prefer unique vendor rank inside a table; otherwise points, wins, then goal difference. tiebreakRules names that fallback only.
  • Client apps should tolerate propagation delay immediately after sync events.

Troubleshooting checklist

  1. Verify source repo workflow completed successfully.
  2. Confirm webhook auth configuration.
  3. Re-run admin sync routes for remediation if needed.
  4. Validate refreshed payloads from /api/teams and /api/leagues.