Star Wars Unlimited Stats
Welcome to the SWU Stats API documentation. This page provides information about available APIs. Please note that some APIs may have rate limits or require authentication. For high-volume usage, please contact us to discuss your needs. There is no charge to use SWU Stats APIs, but we ask that you visibly credit SWU Stats on your site if you use them. If you have any questions or need assistance with our APIs, please join our Discord server.
Access statistical information about decks, including win rates, matchups, and more.
GET /TCGEngine/Stats/DeckMetaStatsAPI.php
Retrieve statistics for decks based on different parameters.
| Parameter | Type | Description |
|---|---|---|
| deckId | integer | The ID of the deck to retrieve stats for |
| startWeek | integer | (Optional) Include weeks ≥ startWeek. If BOTH startWeek and endWeek are omitted, all weeks are included (all-time). Results are aggregated across the selected weeks. |
| endWeek | integer | (Optional) Include weeks ≤ endWeek. With both provided, the inclusive range is used; with only endWeek, weeks 0..endWeek. |
| format | string | (Optional) Filter by game format |
{
"leaderID": "0524529055",
"leaderTitle": "Snap Wexley",
"leaderSubtitle": "Resistance Recon Expert",
"baseID": "1029978899",
"baseTitle": "Colossus",
"baseSubtitle": "",
"numPlays": 42,
"winRate": "66.67",
"avgTurnsInWins": "7.76",
"avgTurnsInLosses": "8.36",
"avgCardsResourcedInWins": "8.02",
"avgRemainingHealthInWins": "12.28"
}
Modify a deck you own (add or remove cards). This endpoint requires OAuth authentication with the 'decks' scope and the caller must be the deck owner.
POST /TCGEngine/APIs/EditDeckCard.php
This endpoint requires an OAuth access token. Provide the token via one of the following:
Authorization: Bearer {access_token}{"access_token": "{access_token}"} (recommended for local testing where Authorization headers may be stripped)Required scope: decks — the token must include the decks scope or the API will return HTTP 403 (insufficient_scope).
{
"access_token": "your_oauth_token", // or provide in Authorization header
"deckID": 123, // integer deck id
"action": "add|remove", // add or remove
"cardID": "CARD_UID", // card id used in gamestate
"count": 1, // number to add/remove (optional, default 1)
"zone": "main|side" // zone to change (optional, default "main")
}
POST /TCGEngine/APIs/EditDeckCard.php
{
"success": true,
"deckID": 123,
"action": "remove",
"cardID": "CARD_UID",
"zone": "main",
"removed": 1
}
{
"success": false,
"errors": {
"access_token": "Missing access token"
}
}
// or
{
"success": false,
"errors": {
"access_token": "Invalid or expired"
}
}
{
"success": false,
"error": "Not deck owner"
}
If the provided access token does not include the required scope the API returns HTTP 403 with the following body:
{
"success": false,
"error": "insufficient_scope",
"required": "decks"
}
{
"success": false,
"error": "Card not found in specified zone"
}
Retrieve all matchup statistics across all leader/base combinations. Useful for bulk analysis or building aggregated views.
GET /TCGEngine/APIs/MetaMatchupStatsAPI.php
Returns the whole-meta matchup grid. By default results are aggregated across ALL weeks (all-time); use the week parameters to restrict the window, or groupByWeek=1 for a per-week breakdown.
| Parameter | Type | Description |
|---|---|---|
| startWeek | integer | (Optional) Include weeks ≥ startWeek. If both week params are omitted, all weeks are included (all-time). |
| endWeek | integer | (Optional) Include weeks ≤ endWeek. With both provided, the inclusive range is used; with only endWeek, weeks 0..endWeek. |
| groupByWeek | integer | (Optional) Set to 1 to return one row per matchup PER WEEK (each row includes a week field), for tracking change over time. Default aggregates the selected weeks into one row per matchup. |
[
{
"leaderID": "0524529055",
"baseID": "1029978899",
"opponentLeaderID": "1234567890",
"opponentBaseID": "0987654321",
"numWins": 12,
"numPlays": 30,
"playsGoingFirst": 15,
"turnsInWins": 90,
"totalTurns": 210,
"cardsResourcedInWins": 80,
"totalCardsResourced": 200,
"remainingHealthInWins": 45,
"winsGoingFirst": 7,
"winsGoingSecond": 5
}
// More matchup objects...
]
Access detailed matchup statistics for a specific deck (leader + base combination) against all other decks.
GET /TCGEngine/APIs/DeckMetaMatchupStatsAPI.php
Retrieve matchup statistics for a deck, showing how it performs against other leader/base combinations. By default results are aggregated across ALL weeks (all-time); use the week parameters to restrict the window, or groupByWeek=1 for a per-week breakdown.
| Parameter | Type | Description |
|---|---|---|
| leaderID | string | The ID of the leader for the deck (required) |
| baseID | string | The ID of the base for the deck (required) |
| startWeek | integer | (Optional) Include weeks ≥ startWeek. If both week params are omitted, all weeks are included (all-time). |
| endWeek | integer | (Optional) Include weeks ≤ endWeek. With both provided, the inclusive range is used; with only endWeek, weeks 0..endWeek. |
| groupByWeek | integer | (Optional) Set to 1 to return one row per opponent PER WEEK (each row includes a week field), for tracking change over time. Default aggregates the selected weeks into one row per opponent. |
[
{
"opponentLeaderID": "1234567890",
"opponentBaseID": "0987654321",
"numWins": 12,
"numPlays": 30,
"playsGoingFirst": 15,
"turnsInWins": 90,
"totalTurns": 210,
"cardsResourcedInWins": 80,
"totalCardsResourced": 200,
"remainingHealthInWins": 45,
"winsGoingFirst": 7,
"winsGoingSecond": 5
}
// More matchup objects...
]
Access statistical information about individual cards, including play rates, resource rates, and more.
GET /TCGEngine/Stats/CardMetaStatsAPI.php
Retrieve statistics for individual cards based on different parameters.
| Parameter | Type | Description |
|---|---|---|
| cardId | string | The ID of the card to retrieve stats for |
| startWeek | integer | (Optional) Include weeks ≥ startWeek. If BOTH startWeek and endWeek are omitted, all weeks are included (all-time). Results are aggregated across the selected weeks. |
| endWeek | integer | (Optional) Include weeks ≤ endWeek. With both provided, the inclusive range is used; with only endWeek, weeks 0..endWeek. |
| format | string | (Optional) Filter by game format |
{
"cardId": "CARD123",
"name": "Example Card",
"timesIncluded": 1500,
"timesPlayed": 850,
"timesResourced": 420,
"playRate": 56.7,
"resourceRate": 28.0,
"winRateWhenPlayed": 62.3
}
Submit game results to be included in our statistics database. An API key is required to use this endpoint. Reach out on Discord to get an API key.
POST /TCGEngine/APIs/SubmitGameResult.php
{
"apiKey": "your_api_key", // Your API key
"winner": 1, // 1 for player 1, 2 for player 2, 0 for draw
"firstPlayer": 1, // 1 for player 1, 2 for player 2
"round": 10, // Number of turns/rounds played
"winnerHealth": 5, // Health remaining for winner
"winHero": "Red Hero", // Winner's hero/leader
"loseHero": "Blue Hero", // Loser's hero/leader
"winnerDeck": "Deck List", // Winner's deck contents
"loserDeck": "Deck List", // Loser's deck contents
"player1": "{...}", // Player 1 stats JSON
"player2": "{...}", // Player 2 stats JSON
"p1DeckLink": "https://swustats.net/path/to/deck?gameName=1234",
"p2DeckLink": "https://swustats.net/path/to/deck?gameName=5678",
"p1id": "player1_id", // Optional player IDs
"p2id": "player2_id",
"format": "premier", // Optional: game format (default: "premier"). Examples: "premier", "preview"
"disableMetaStats": false, // Optional: set to true if one or more players opts out of meta stats collection
"gameName": "12345", // Game identifier
"sequenceNumber": 1 // Optional sequence number for BO3 matches
}
The player stats JSON contains detailed information about a player's performance in the game, including card usage and turn-by-turn statistics.
{
"gameId": "12345", // Unique game identifier (optional)
"gameName": "match_12345", // Custom game name (optional)
"deckId": "NextTurn.php?gameName=1787&playerID=1&folderPath=SWUDeck", // The last part of the deck link
"leader": "12345", // Leader id (FFG UID format)
"base": "12345", // Base id (FFG UID format)
"turns": 8, // Number of turns played
"result": 1, // 1 if this player won, 0 for loss
"firstPlayer": 1, // 1 if this player went first, 0 otherwise
"opposingHero": "12345", // Opponent's leader id (FFG UID format)
"opposingBaseColor": "Red", // Opponent's base color (Red, Blue, Yellow, Green, Colorless)
"opposingBase": "5396502974", // (Optional, preferred) Opponent's base card id (FFG UID). When present and recognized, matchup stats bucket by base type (Standard/Force/Splash). Falls back to opposingBaseColor when absent or unrecognized.
"deckbuilderID": "user_42", // Deckbuilder user ID
"cardResults": [
{
"cardId": "12345", // Card id (FFG UID format)
"played": 1, // Times played
"resourced": 1, // Times used as resource
"activated": 2, // Times ability activated
"drawn": 2, // Times drawn
"discarded": 0 // Times discarded
},
// More cards...
],
"turnResults": [
{
"cardsUsed": 3, // Cards played this turn
"resourcesUsed": 4, // Resources spent
"resourcesLeft": 0, // Resources remaining
"cardsLeft": 2, // Cards left in hand
"damageDealt": 5, // Damage dealt this turn
"damageTaken": 3 // Damage received this turn
},
// More turn results...
]
}
Matchup stats read back via SWUDeck/GetCardTextJSON.php?deckID=<id> now include baseType ("Legacy" | "Standard" | "Force" | "Splash" | "Named") and baseName alongside baseColor. Common bases are one row per (opponent leader, color, type); Rare/Special bases are one row per (opponent leader, base) with baseType="Named" and baseName set to the base's card name.
{
"success": true,
"gameResultID": 12345
}
If one or more provided SWU OAuth tokens are invalid or expired the API returns a 401 with a structured errors object describing which token(s) failed.
{
"success": false,
"errors": {
"p1SWUStatsToken": "Invalid or expired",
"p2SWUStatsToken": "Invalid or expired"
}
}
Access information about Melee tournaments including tournament details, links, and dates.
GET /TCGEngine/APIs/GetMeleeTournaments.php
Retrieve a list of Melee tournaments with optional filtering and pagination.
| Parameter | Type | Description |
|---|---|---|
| id | integer | (Optional) Specific tournament ID to retrieve |
| limit | integer | (Optional) Maximum number of tournaments to return (default: 50) |
| offset | integer | (Optional) Number of tournaments to skip for pagination (default: 0) |
| date_from | string | (Optional) Filter tournaments after this date (YYYY-MM-DD) |
| date_to | string | (Optional) Filter tournaments before this date (YYYY-MM-DD) |
| sort | string | (Optional) Sort tournaments by field and direction (e.g., "tournamentDate DESC", default: "tournamentDate DESC") |
| format | string | (Optional) Response format: "json" or "html" (default: "json") |
{
"success": true,
"total": 42,
"count": 20,
"offset": 0,
"limit": 20,
"tournaments": [
{
"id": 1,
"name": "Star Wars: Unlimited Sector Qualifier - Milan, Italy | Melee",
"date": "2025-03-30",
"link": 270771,
"melee_url": "https://melee.gg/tournament/270771"
},
// More tournaments...
]
}
GET /TCGEngine/APIs/GetMeleeTournament.php
Retrieve detailed information for a specific Melee tournament, including standings, matchups, and player statistics.
| Parameter | Type | Description |
|---|---|---|
| id | integer | (Required) The ID of the tournament to retrieve details for |
| include_matchups | integer | (Optional) Set to 1 to include detailed matchup data (default: 0) |
{
"success": true,
"tournament": {
"id": 1,
"name": "Star Wars: Unlimited Sector Qualifier - Milan, Italy | Melee",
"date": "2025-03-30",
"link": 270771,
"round_id": 977630,
"melee_url": "https://melee.gg/tournament/270771"
},
"decks_count": 32,
"decks": [
{
"id": 1,
"player": "PlayerName",
"meleeId": 123456,
"rank": 1,
"standings": {
"match_record": "7-0-0",
"match_wins": 7,
"match_losses": 0,
"match_draws": 0,
"match_win_rate": 100,
"game_record": "14-2-0",
"game_wins": 14,
"game_losses": 2,
"game_draws": 0,
"game_win_rate": 87.5
},
"points": 21,
"tiebreakers": {
"omwp": 68.57,
"tgwp": 87.5,
"ogwp": 65.24
},
"matchups": [
{
"opponent_id": 5,
"opponent_name": "OpponentName",
"wins": 2,
"losses": 0,
"draws": 0,
"result": "2-0-0"
},
// More matchups...
]
},
// More decks/players...
]
}
Access and manage deck information.
GET /TCGEngine/APIs/UserAPIs/GetUserDecks.php
Retrieve a list of decks owned by the authenticated user, including those marked as favorites. This API requires OAuth authentication with the 'decks' scope.
This endpoint requires OAuth 2.0 authentication with the 'decks' scope. The access token must be provided in one of the following ways:
Authorization: Bearer {access_token}access_token={access_token}| Parameter | Type | Description |
|---|---|---|
| limit | integer | (Optional) Maximum number of decks to return (default: 100) |
| offset | integer | (Optional) Number of decks to skip for pagination (default: 0) |
| sort | string | (Optional) Sort field: 'name' or 'date' (default: 'name') |
| order | string | (Optional) Sort order: 'asc' or 'desc' (default: 'asc') |
| favorites | string | (Optional) Set to 'true' to only return favorite decks |
{
"decks": [
{
"id": 123,
"name": "My Favorite Deck",
"description": "A powerful deck for tournaments",
"visibility": 1,
"created_at": "2025-01-01 12:00:00",
"updated_at": "2025-04-20 15:30:00",
"is_favorite": true
},
{
"id": 456,
"name": "Another Deck",
"description": "Casual play deck",
"visibility": 2,
"created_at": "2025-02-15 09:30:00",
"updated_at": "2025-04-18 14:15:00",
"is_favorite": false
}
],
"pagination": {
"total": 42,
"limit": 100,
"offset": 0,
"has_more": false
}
}
GET /TCGEngine/APIs/LoadDeck.php
Load a deck by its ID.
| Parameter | Type | Description |
|---|---|---|
| deckID | integer | The ID of the deck to load |
{
"deckId": 12345,
"name": "Example Deck",
"hero": "Red Hero",
"cards": [
{
"cardId": "CARD123",
"count": 3
},
// More cards...
]
}
GET /TCGEngine/AIEndpoints/FullElasticSearchOAuth.php
Search for cards using OAuth authentication. Requires a valid OAuth access token with the 'search' scope. User must be a current Patreon subscriber.
| Parameter | Type | Description |
|---|---|---|
| request | string | The natural language card search query (URL encoded) |
| access_token | string | OAuth access token with 'search' scope (or provide via Authorization header) |
{
"message": "specificCards=uuid1,uuid2,uuid3,uuid4,uuid5"
}