SWU API
Star Wars Unlimited Card Data API
Overview
The SWU API provides programmatic access to Star Wars Unlimited card data and competitive tournament results. All responses are JSON.
Public endpoints (no authentication required): Cards & Sets, Export, Archetypes, Metas, Sync, Deck Image.
Private endpoints (API key required): Tournaments, Players, Matches, Decklists. Pass your key as a Bearer token: Authorization: Bearer <key>
Base URL
https://api.swuapi.com
Health check endpoint. Returns server status and last scrape info.
curl https://api.swuapi.com/health
const response = await fetch('https://api.swuapi.com/health');
const data = await response.json();
console.log(data.status); // "healthy"
{
"status": "healthy",
"cardCount": 5560,
"lastScrape": {
"completedAt": "2024-01-15T06:00:00.000Z",
"status": "success",
"cardsFound": 5560
},
"uptime": 3600
}
List all card sets/expansions.
curl https://api.swuapi.com/sets
const response = await fetch('https://api.swuapi.com/sets');
const { sets } = await response.json();
sets.forEach(set => {
console.log(`${set.code}: ${set.name}`);
});
{
"sets": [
{
"code": "SOR",
"name": "Spark of Rebellion",
"release_date": "2024-03-08",
"total_cards": 252
},
{
"code": "SHD",
"name": "Shadows of the Galaxy",
"release_date": "2024-07-12",
"total_cards": 262
}
]
}
Get a single set by its code.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
code |
string | Set code (e.g., SOR, SHD, TWI) |
curl https://api.swuapi.com/sets/SOR
const setCode = 'SOR';
const response = await fetch(`https://api.swuapi.com/sets/${setCode}`);
const set = await response.json();
console.log(set.name); // "Spark of Rebellion"
{
"code": "SOR",
"name": "Spark of Rebellion",
"release_date": "2024-03-08",
"total_cards": 252
}
List cards with pagination and optional filtering.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 100 | Number of cards to return (max 500) |
offset |
integer | 0 | Number of cards to skip |
after |
string | - | UUID cursor for forward pagination. Pass next_cursor from the previous response. Alias: ?cursor=. |
set |
string | - | Filter by set code (e.g., SOR, SHD) |
type |
string | - | Filter by type (Leader, Unit, Event, Upgrade, Base) |
rarity |
string | - | Filter by rarity (Common, Uncommon, Rare, Legendary, Special) |
name |
string | - | Search by card name or subtitle (case-insensitive partial match) |
# Get first 100 cards
curl https://api.swuapi.com/cards
# Get leaders from Spark of Rebellion
curl "https://api.swuapi.com/cards?set=SOR&type=Leader"
# Search by name
curl "https://api.swuapi.com/cards?name=Bossk"
# Paginate through results
curl "https://api.swuapi.com/cards?limit=50&offset=100"
// Get all leaders from SOR
const params = new URLSearchParams({
set: 'SOR',
type: 'Leader',
limit: 50
});
const response = await fetch(
`https://api.swuapi.com/cards?${params}`
);
const { cards, pagination } = await response.json();
console.log(`Found ${pagination.total} cards`);
cards.forEach(card => console.log(card.name));
{
"cards": [
{
"id": "SOR_005",
"name": "Luke Skywalker",
"subtitle": "Faithful Friend",
"type": "Leader",
"rarity": "Special",
// ... see Card Object for all fields
}
],
"pagination": {
"limit": 100,
"offset": 0,
"total": 5560
}
}
Get a single card by any identifier: UUID, external_id (integer), collector_number (SOR_005), or card name slug (e.g., "entrenched").
Variant note: collector_number is shared between variants (e.g. SOR_005 is both Luke Standard and Luke Foil). Lookups by collector_number or name slug always return the Standard variant by default. Use ?variant= to request a different variant. UUID and external_id are unique per variant and ignore this parameter.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id |
string | int | uuid | UUID, external_id (integer), collector_number (e.g., SOR_005), or card name slug |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
variant |
string | Standard |
Filter by variant_type when looking up by collector_number or name slug. Common values: Standard, Hyperspace, Showcase. Use all to return an array of every variant sharing the same collector_number. Ignored for UUID and external_id lookups. |
# By UUID (unique, stable)
curl https://api.swuapi.com/cards/59e4854c-bd67-47f2-98c9-815d31736928
# By external_id (unique per variant)
curl https://api.swuapi.com/cards/5
# By collector_number — returns Standard variant by default
curl https://api.swuapi.com/cards/SOR_005
# By collector_number — request Hyperspace variant explicitly
curl https://api.swuapi.com/cards/SOR_005?variant=Hyperspace
# By collector_number — return all variants as an array
curl https://api.swuapi.com/cards/SOR_005?variant=all
# By slug
curl https://api.swuapi.com/cards/entrenched
const response = await fetch(
'https://api.swuapi.com/cards/59e4854c-bd67-47f2-98c9-815d31736928'
);
const card = await response.json();
console.log(card.uuid); // "59e4854c-..."
console.log(card.collector_number); // "SOR_005"
console.log(card.external_id); // 5
{
"uuid": "59e4854c-bd67-47f2-98c9-815d31736928",
"external_id": 5,
"collector_number": "SOR_005",
"external_uid": "2579145458",
"name": "Luke Skywalker",
"subtitle": "Faithful Friend",
"setCode": "SOR",
"cardNumber": "5",
"type": "Leader",
"type2": "Leader Unit",
"rarity": "Special",
"cost": 6,
"power": 4,
"hp": 7,
"arena": "Ground",
"aspects": ["Vigilance", "Heroism"],
"traits": ["Force", "Rebel"],
"keywords": [],
"variantType": "Standard",
"text": "Action [1 resource, exhaust]: Give a Shield token...",
"deployBox": "On Attack: You may give another unit a Shield token.",
"epicAction": "Epic Action: If you control 6 or more resources...",
"isUnique": true,
"isLeader": true,
"frontImageUrl": "https://cdn.starwarsunlimited.com/...",
"backImageUrl": "https://cdn.starwarsunlimited.com/...",
"artist": "Borja Pindado",
"variants": [981, 9745],
"variantOf": null,
"reprints": [100],
"reprintOf": null
}
Export all cards and sets as a single JSON payload. Useful for bulk imports or syncing.
# Download full export
curl https://api.swuapi.com/export/all -o cards.json
# Pipe to jq for processing
curl -s https://api.swuapi.com/export/all | jq '.meta'
const response = await fetch(
'https://api.swuapi.com/export/all'
);
const { cards, sets, meta } = await response.json();
console.log(`Total cards: ${meta.totalCards}`);
console.log(`Total sets: ${meta.totalSets}`);
console.log(`Last scraped: ${meta.lastScrapedAt}`);
// Process all cards
const leaders = cards.filter(c => c.type === 'Leader');
console.log(`Found ${leaders.length} leaders`);
{
"cards": [
{ /* card objects */ }
],
"sets": [
{ /* set objects */ }
],
"meta": {
"totalCards": 5560,
"totalSets": 19,
"lastScrapedAt": "2024-01-15T06:00:00.000Z",
"exportedAt": "2024-01-15T12:00:00.000Z"
}
}
List SWU tournaments. Includes competitive events (PQ, SQ, RQ, GC, LCQ), Store Showdowns (SS), community events (COM), and casual side events (CAS).
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 50 | Number of tournaments to return (max 200) |
offset |
integer | 0 | Number of tournaments to skip |
after |
string | - | UUID cursor for forward pagination. Pass next_cursor from the previous response. Alias: ?cursor=. |
tier |
string | - | Filter by tier: PQ, SQ, RQ, GC, LCQ, SS, COM, CAS |
format |
string | - | Filter by format: Premiere, Limited |
official |
boolean | - | Filter by official status (true = FFG-sanctioned, false = community) |
# List all tournaments
curl https://api.swuapi.com/tournaments
# Filter by tier and format
curl "https://api.swuapi.com/tournaments?tier=PQ&format=Premiere"
const response = await fetch(
'https://api.swuapi.com/tournaments?tier=SQ'
);
const { tournaments, pagination } = await response.json();
console.log(`Found ${pagination.total} Sector Qualifiers`);
{
"tournaments": [
{
"melee_id": 67890,
"name": "Star Wars: Unlimited Planetary Qualifier Austin",
"display_name": "Planetary Qualifier (SEC) — Austin, TX, US",
"date": "2026-02-15T00:00:00.000Z",
"tier": "PQ",
"tier_level": "competitive",
"format": "Premiere",
"official": true,
"organizer": "Emerald Tavern Games",
"player_count": 64,
"has_day_two": true,
"day_one_swiss_rounds": 8,
"day_two_swiss_rounds": 4,
"round_structure": {
"has_day_two": true,
"total_swiss_rounds": 12,
"day_two_start_round": 9,
"days": [
{ "day": 1, "start_round": 1, "end_round": 8, "swiss_round_count": 8 },
{ "day": 2, "start_round": 9, "end_round": 12, "swiss_round_count": 4 }
]
},
"melee_url": "https://melee.gg/Tournament/View/67890",
"event_type": "main"
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 130
}
}
Get a single tournament by its ID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
meleeId |
integer | Tournament ID |
curl https://api.swuapi.com/tournaments/67890
{
"melee_id": 67890,
"name": "Star Wars: Unlimited Planetary Qualifier Austin",
"date": "2026-02-15T00:00:00.000Z",
"tier": "PQ",
"format": "Premiere",
"organizer": "Emerald Tavern Games",
"player_count": 64,
"has_day_two": true,
"day_one_swiss_rounds": 8,
"day_two_swiss_rounds": 4,
"round_structure": {
"has_day_two": true,
"total_swiss_rounds": 12,
"day_two_start_round": 9,
"days": [
{ "day": 1, "start_round": 1, "end_round": 8, "swiss_round_count": 8 },
{ "day": 2, "start_round": 9, "end_round": 12, "swiss_round_count": 4 }
]
},
"melee_url": "https://melee.gg/Tournament/View/67890",
"event_type": "main"
}
List live and upcoming tournaments with current-round metadata. Multi-day melee events include inferred Day 1 / Day 2 Swiss structure and the current round’s tournament day.
curl https://api.swuapi.com/tournaments/live
{
"tournaments": [
{
"melee_id": 414243,
"name": "Sector Qualifier - Atlanta - Saturday - 10:00 am",
"status": "live",
"has_day_two": true,
"day_one_swiss_rounds": 8,
"day_two_swiss_rounds": 4,
"round_structure": {
"day_two_start_round": 9,
"days": [
{ "day": 1, "start_round": 1, "end_round": 8, "swiss_round_count": 8 },
{ "day": 2, "start_round": 9, "end_round": 12, "swiss_round_count": 4 }
]
},
"current_round": 8,
"current_round_name": "Round 8",
"current_round_day": 1,
"round_count": 15
}
]
}
Return all rounds for a tournament. Each round includes round_stage (swiss or top_cut) and tournament_day inferred from melee’s public event schedule when available.
curl https://api.swuapi.com/tournaments/414243/rounds
{
"round_structure": {
"has_day_two": true,
"total_swiss_rounds": 12,
"day_two_start_round": 9,
"days": [
{ "day": 1, "start_round": 1, "end_round": 8, "swiss_round_count": 8 },
{ "day": 2, "start_round": 9, "end_round": 12, "swiss_round_count": 4 }
]
},
"rounds": [
{
"round_number": 8,
"round_name": "Round 8",
"is_top_cut": false,
"round_stage": "swiss",
"tournament_day": 1,
"pairing_count": 64
},
{
"round_number": 9,
"round_name": "Round 9",
"is_top_cut": false,
"round_stage": "swiss",
"tournament_day": 2,
"pairing_count": 0
},
{
"round_number": 100,
"round_name": "Quarterfinals",
"is_top_cut": true,
"round_stage": "top_cut",
"tournament_day": 2
}
]
}
Get all match results for a tournament, ordered by round number. Includes player names via join and a derived draw_type field (intentional, played, or null).
curl https://api.swuapi.com/tournaments/67890/matches
{
"tournament": { "melee_id": 67890, "name": "PQ Austin", ... },
"matches": [
{
"id": 1,
"round_number": 1,
"is_top_cut": false,
"player1_account_melee_id": "abc-123",
"player1_id": 42,
"player1_name": "Alice",
"player2_account_melee_id": "def-456",
"player2_id": 17,
"player2_name": "Bob",
"player1_wins": 2,
"player2_wins": 1,
"draws": 0,
"draw_type": null,
"winner_account_melee_id": "abc-123",
"winner_id": 42,
"is_bye": false,
"is_forfeit": false
}
]
}
Get all submitted decklists for a tournament. Responses include archetype-derived leader/base fields so consumers can render leader + base without a second archetype lookup.
curl https://api.swuapi.com/tournaments/67890/decklists
{
"tournament": { "melee_id": 67890, "name": "PQ Austin", ... },
"decklists": [
{
"uuid": "019d9557-...",
"melee_id": "d1e2f3a4-...",
"player_name": "Alice",
"archetype_uuid": "019d323a-...",
"archetype_name": "Darth Vader, Dark Lord of the Sith - Yellow 30",
"leader_name": "Darth Vader",
"leader_subtitle": "Dark Lord of the Sith",
"leader_set_code": "SOR",
"base_name": "Yellow 30",
"leader_collector_number": "SOR_010",
"canonical_base_collector_number": "SOR_179",
"decklist": [
{ "id": "SOR_010", "count": 1 },
{ "id": "SOR_193", "count": 3 }
]
}
]
}
List canonical players, deduplicated across multiple tournament accounts. Sorted by match count descending.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 50 | Number of players to return (max 200) |
offset |
integer | 0 | Number of players to skip |
after |
string | - | UUID cursor for forward pagination. Pass next_cursor from the previous response. Alias: ?cursor=. |
name |
string | - | Search by player name (case-insensitive partial match) |
# Search for a player
curl "https://api.swuapi.com/players?name=skywalker"
{
"players": [
{
"id": 42,
"name": "42Mops",
"account_count": "2",
"tournament_count": "3",
"match_count": "25"
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 1
}
}
Get a single player by their canonical ID. Also accepts an account ID as fallback.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id |
integer|string | Player ID (integer) or account ID (string) |
curl https://api.swuapi.com/players/42
{
"id": 42,
"name": "Alice",
"account_count": "2",
"accounts": [
{ "melee_id": "abc-123", "name": "Alice" },
{ "melee_id": "def-456", "name": "Alice" }
]
}
Get all matches for a player across all tournaments and accounts. Includes tournament name, tier, and canonical player IDs.
curl https://api.swuapi.com/players/42/matches
{
"player": { "id": 42, "name": "Alice" },
"matches": [
{
"id": 42,
"tournament_name": "PQ Austin",
"tier": "PQ",
"format": "Premiere",
"round_number": 3,
"player1_id": 42,
"player1_name": "Alice",
"player2_id": 17,
"player2_name": "Bob",
"player1_wins": 2,
"player2_wins": 0,
"draw_type": null
}
]
}
Get all decklists submitted by a player across tournaments and accounts. Responses include archetype-derived leader/base fields.
curl https://api.swuapi.com/players/42/decklists
{
"player": { "id": 42, "name": "Alice" },
"decklists": [
{
"uuid": "019d9557-...",
"melee_id": "d1e2f3a4-...",
"tournament_name": "PQ Austin",
"tier": "PQ",
"archetype_uuid": "019d323a-...",
"archetype_name": "Darth Vader, Dark Lord of the Sith - Yellow 30",
"leader_name": "Darth Vader",
"base_name": "Yellow 30",
"decklist": [ ... ]
}
]
}
List matches across all tournaments with pagination and optional filters. Each match includes a derived draw_type field so intentional draws (0-0-3) can be separated from played draws.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 50 | Number of matches to return (max 200) |
offset |
integer | 0 | Number of matches to skip |
after |
string | - | UUID cursor for forward pagination. Pass next_cursor from the previous response. Alias: ?cursor=. |
tournament |
integer | - | Filter by tournament melee_id |
account |
string | - | Filter by account ID |
# Get all matches for a tournament
curl "https://api.swuapi.com/matches?tournament=67890"
# Get all matches for an account
curl "https://api.swuapi.com/matches?account=abc-123-def"
{
"matches": [
{
"id": 1,
"tournament_melee_id": 67890,
"tournament_name": "PQ Austin",
"round_number": 1,
"player1_id": 42,
"player1_name": "Alice",
"player2_id": 17,
"player2_name": "Bob",
"player1_wins": 2,
"player2_wins": 1,
"draws": 0,
"draw_type": null,
"winner_id": 42
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 24929
}
}
Get a single match by its database ID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id |
integer | Match database ID |
curl https://api.swuapi.com/matches/42
{
"id": 42,
"tournament_melee_id": 67890,
"tournament_name": "PQ Austin",
"round_number": 3,
"is_top_cut": false,
"player1_account_melee_id": "abc-123",
"player1_id": 42,
"player1_name": "Alice",
"player2_account_melee_id": "def-456",
"player2_id": 17,
"player2_name": "Bob",
"player1_wins": 2,
"player2_wins": 0,
"draws": 0,
"draw_type": null,
"winner_account_melee_id": "abc-123",
"winner_id": 42,
"is_bye": false,
"is_forfeit": false
}
List decklists across all tournaments with pagination and filters. Each row includes archetype-derived leader/base fields so downstream consumers do not need to join archetypes separately.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 50 | Number of decklists to return (max 200) |
offset |
integer | 0 | Number of decklists to skip |
after |
string | - | UUID cursor for forward pagination. Pass next_cursor from the previous response. Alias: ?cursor=. |
tournament |
integer | - | Filter by tournament melee_id |
account |
string | - | Filter by account ID |
archetype |
string | - | Search by archetype name (case-insensitive partial match) |
hasCards |
boolean | - | Filter to only decklists with card data (true) |
# Find all Darth Vader decklists
curl "https://api.swuapi.com/decklists?archetype=Vader"
# Get decklists for a specific tournament
curl "https://api.swuapi.com/decklists?tournament=67890"
{
"decklists": [
{
"uuid": "019d9557-...",
"melee_id": "d1e2f3a4-...",
"archetype_uuid": "019d323a-...",
"archetype_name": "Darth Vader, Dark Lord of the Sith - Yellow 30",
"leader_name": "Darth Vader",
"leader_subtitle": "Dark Lord of the Sith",
"leader_set_code": "SOR",
"base_name": "Yellow 30",
"leader_collector_number": "SOR_010",
"canonical_base_collector_number": "SOR_179",
"player_name": "Alice",
"tournament_name": "PQ Austin",
"tier": "PQ",
"decklist": [
{ "id": "SOR_010", "count": 1 }
]
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 5216
}
}
Get a single decklist by its ID. Includes the full decklist plus archetype-derived leader/base fields.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
meleeId |
string | Decklist ID (UUID) |
curl https://api.swuapi.com/decklists/d1e2f3a4-5678-90ab-cdef
{
"uuid": "019d9557-...",
"melee_id": "d1e2f3a4-...",
"account_uuid": "019d9557-c54d-...",
"player_name": "Alice",
"tournament_uuid": "019d83a7-1155-...",
"archetype_uuid": "019d323a-...",
"archetype_name": "Darth Vader, Dark Lord of the Sith - Yellow 30",
"leader_name": "Darth Vader",
"leader_subtitle": "Dark Lord of the Sith",
"leader_set_code": "SOR",
"base_name": "Yellow 30",
"leader_collector_number": "SOR_010",
"canonical_base_collector_number": "SOR_179",
"decklist": [
{ "id": "SOR_010", "count": 1 },
{ "id": "SOR_193", "count": 3 }
],
"tournament_name": "PQ Austin",
"tier": "PQ",
"format": "Premiere"
}
List archetypes (leader + normalized base combinations) with pagination and search. Common bases are normalized to color+HP (e.g., "Yellow30"), rare bases keep their name (e.g., "Tarkintown").
| Parameter | Type | Default | Description |
|---|---|---|---|
format |
string | - | Required. Filter by format: Premiere or Limited. |
limit |
integer | 20 | Number of archetypes to return (max 200) |
after |
string | - | UUID cursor for forward pagination. Pass next_cursor from the previous response. Alias: ?cursor=. |
name |
string | - | Search name or nickname (case-insensitive) |
curl "https://api.swuapi.com/archetypes?format=Premiere"
curl "https://api.swuapi.com/archetypes?format=Premiere&name=Han+Solo"
// Paginate through every Premiere archetype using cursor
let cursor = null
do {
const url = `https://api.swuapi.com/archetypes?format=Premiere${cursor ? `&cursor=${cursor}` : ''}`
const { archetypes, pagination } = await (await fetch(url)).json()
archetypes.forEach(a => console.log(a.name))
cursor = pagination.next_cursor
} while (cursor)
{
"archetypes": [
{
"uuid": "019d3239-22ef-76ec-b412-ac0b8def717a",
"name": "Han Solo, Worth the Risk - Energy Conversion Lab",
"nickname": "Han Solo (SHD) - Energy Conversion Lab",
"format": "Premiere",
"leader_aspects": ["Cunning", "Heroism"],
"base_aspects": ["Vigilance"],
"leader": {
"uuid": "019d3177-...",
"name": "Han Solo",
"subtitle": "Worth the Risk",
"collector_number": "SHD_015",
"image_url": "https://cdn.starwarsunlimited.com/..."
},
"base_group": {
"uuid": "019d363c-...",
"canonical_name": "Energy Conversion Lab"
},
"canonical_base_card": {
"uuid": "019d3178-...",
"collector_number": "SHD_101",
"image_url": "https://cdn.starwarsunlimited.com/..."
},
"decklist_count": 437
}
],
"pagination": { "next_cursor": "019d3239-22ef-76ec-b412-ac0b8def717a" }
}
Get a single archetype by database ID. Includes decklist count.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id |
integer | Archetype database ID |
curl https://api.swuapi.com/archetypes/27
const response = await fetch(
'https://api.swuapi.com/archetypes/27'
)
const archetype = await response.json()
{
"id": 27,
"name": "Han Solo, Worth the Risk - Energy Conversion Lab",
"nickname": "Han Solo (SHD) - Energy Conversion Lab",
"leader_name": "Han Solo",
"leader_subtitle": "Worth the Risk",
"leader_set_code": "SHD",
"base_name": "Energy Conversion Lab",
"base_is_common": false,
"decklist_count": "437"
}
Get all decklists for an archetype. Includes player names and tournament context. Paginated.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id |
integer | Archetype database ID |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 50 | Number of decklists to return (max 200) |
offset |
integer | 0 | Number of decklists to skip |
curl https://api.swuapi.com/archetypes/27/decklists
curl "https://api.swuapi.com/archetypes/27/decklists?limit=10"
const response = await fetch(
'https://api.swuapi.com/archetypes/27/decklists?limit=10'
)
const data = await response.json()
// data.archetype — the archetype object
// data.decklists — array of decklists
// data.pagination — { limit, offset, total }
{
"archetype": {
"id": 27,
"name": "Han Solo, Worth the Risk - Energy Conversion Lab",
"nickname": "Han Solo (SHD) - Energy Conversion Lab"
},
"decklists": [
{
"melee_id": "d1e2f3a4-...",
"player_name": "Alice",
"tournament_name": "Sector Qualifier - Paris",
"tier": "SQ",
"format": "Premiere",
"archetype": "Han Solo, Worth the Risk - Energy Conversion Lab",
"cards": [...]
}
],
"pagination": { "limit": 10, "offset": 0, "total": 437 }
}
Stateless compute: returns the canonical identity (name, nickname, base_group_uuid, aspects) for a given (leader, base, format) tuple. Does NOT create a row. Returns uuid: null if no archetype exists yet for the tuple. Use POST if you want find-or-create.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
leader_card_uuid | string | Yes | UUID of the leader card. |
base_card_uuid | string | Yes | UUID of the base card. |
format | string | Yes | Premiere or Limited. |
curl "https://api.swuapi.com/archetypes/resolve?leader_card_uuid=019d3177-...&base_card_uuid=019d3177-...&format=Premiere"
{
"uuid": "019d3239-22ef-76ec-b412-ac0b8def717a",
"name": "Han Solo, Audacious Smuggler - Yellow 30",
"nickname": "Han Solo (SOR) - Yellow 30",
"format": "Premiere",
"leader_card_uuid": "019d3177-...",
"base_group_uuid": "019d363c-...",
"canonical_base_card_uuid": "019d3178-...",
"leader_aspects": ["Cunning", "Heroism"],
"base_aspects": ["Cunning"]
}
Find-or-create an archetype. Accepts either UUID-based or name-based bodies; UUIDs take precedence if both are present. Returns the archetype's UUID plus canonical identity fields, creating a new row if the (leader, base, format) tuple didn't exist.
Name-based input rejection. If leader_name/leader_subtitle doesn't match an is_leader=true card, or base_name doesn't match either a base_group's canonical_name or an is_base=true card, the request returns 400 (not a silent create). This is a deliberate guardrail against upstream artifacts polluting the catalog.
Request Body (UUID shape)
| Field | Type | Required | Description |
|---|---|---|---|
leader_card_uuid | string | Yes | UUID of the leader card. |
base_card_uuid | string | Yes | UUID of the base card. |
format | string | Yes | Premiere or Limited. |
Request Body (name shape)
| Field | Type | Required | Description |
|---|---|---|---|
leader_name | string | Yes | Leader card name (e.g., "Han Solo"). |
leader_subtitle | string | Yes | Leader subtitle (e.g., "Audacious Smuggler"). Required to disambiguate multiple printings of the same leader name. |
base_name | string | Yes | Base group canonical name (e.g., "Yellow 30", "Force Blue") or specific rare base card name (e.g., "Aldhani Garrison"). |
format | string | Yes | Premiere or Limited. |
Error Codes
| Code | Status | Meaning |
|---|---|---|
missing_param | 400 | Required field not provided. |
invalid_format | 400 | format must be Premiere or Limited. |
leader_name_not_found | 400 | (name-shape) leader_name does not match any is_leader=true card. Don't retry — fix the input. |
base_name_not_found | 400 | (name-shape) base_name does not match any base_group or is_base=true card. |
leader_not_found | 404 | (UUID-shape) the given leader_card_uuid does not exist. |
base_not_found | 404 | (UUID-shape) the given base_card_uuid does not exist. |
not_a_leader | 400 | Card exists but is not flagged is_leader=true. |
not_a_base | 400 | Card exists but is not flagged is_base=true. |
# Name-based (Wayfinder-style)
curl -X POST https://api.swuapi.com/archetypes/resolve \
-H "Content-Type: application/json" \
-d '{
"leader_name": "Han Solo",
"leader_subtitle": "Audacious Smuggler",
"base_name": "Yellow 30",
"format": "Premiere"
}'
# UUID-based
curl -X POST https://api.swuapi.com/archetypes/resolve \
-H "Content-Type: application/json" \
-d '{
"leader_card_uuid": "019d3177-...",
"base_card_uuid": "019d3178-...",
"format": "Premiere"
}'
{
"uuid": "019d3239-22ef-76ec-b412-ac0b8def717a",
"name": "Han Solo, Audacious Smuggler - Yellow 30",
"nickname": "Han Solo (SOR) - Yellow 30",
"format": "Premiere",
"leader_card_uuid": "019d3177-...",
"base_group_uuid": "019d363c-...",
"canonical_base_card_uuid": "019d3178-...",
"leader_aspects": ["Cunning", "Heroism"],
"base_aspects": ["Cunning"]
}
Batch-reconcile archetype UUIDs against the current server state. For each input UUID, returns whether it's still active, has been merged into another archetype (with to_uuid pointing at the terminal of the merge chain), or is missing entirely. Designed for downstream caches to prune stale entries after migrations or upstream deletions.
Request Body
| Field | Type | Description |
|---|---|---|
uuids | string[] | Array of archetype UUIDs (max 1000 per request). |
curl -X POST https://api.swuapi.com/archetypes/reconcile \
-H "Content-Type: application/json" \
-d '{"uuids": ["019d3239-22ef-76ec-b412-ac0b8def717a", "019d3db5-e3d3-79e4-b339-941b02248012", "00000000-0000-7000-8000-000000000000"]}'
{
"results": [
{ "uuid": "019d3239-22ef-76ec-b412-ac0b8def717a", "status": "active" },
{ "uuid": "019d3db5-e3d3-79e4-b339-941b02248012", "status": "merged",
"to_uuid": "019d3239-22ef-76ec-b412-ac0b8def717a" },
{ "uuid": "00000000-0000-7000-8000-000000000000", "status": "missing" }
]
}
Generate a deck image (PNG) from a JSON card list or text decklist. Returns the image directly. Cards are resolved against the card database for art. Supports custom branding and card variant art.
Request Body
Send either JSON (Content-Type: application/json) or plain text decklist (Content-Type: text/plain).
JSON Fields
| Field | Type | Required | Description |
|---|---|---|---|
cards | array | * | Array of card objects (see below) |
text | string | * | Text decklist (e.g., "1 Han Solo (SOR) 017"). Use instead of cards |
title | string | No | Title text (default: leader name or "Deck") |
subtitle | string | No | Subtitle text (e.g., player name, event) |
date | string | No | Date string to display |
branding | object | No | { url: "yoursite.com" } — override default swuapi branding |
* Provide either cards or text, not both.
Card Object
| Field | Type | Description |
|---|---|---|
name | string | Card name (e.g., "Han Solo, Audacious Smuggler") |
type | string | "Leader", "Base", "Ground Unit", "Space Unit", "Event", "Upgrade" |
count | integer | Number of copies (default 1) |
variant | string | Card variant for art (e.g., "Hyperspace", "Showcase"). Falls back to Standard |
Text Decklist Format
Standard decklist format: COUNT NAME (SET) NUMBER, one card per line.
# JSON format
curl -X POST https://api.swuapi.com/deck-image \
-H "Content-Type: application/json" \
-d '{
"cards": [
{"name": "Han Solo, Audacious Smuggler", "type": "Leader", "variant": "Hyperspace"},
{"name": "Mos Eisley", "type": "Base"},
{"name": "Millennium Falcon, Piece of Junk", "type": "Space Unit", "count": 3},
{"name": "Cunning", "type": "Event", "count": 3}
],
"title": "Han Solo Aggro",
"subtitle": "by terronk"
}' --output deck.png
# Text decklist format
curl -X POST https://api.swuapi.com/deck-image \
-H "Content-Type: application/json" \
-d '{
"text": "1 Han Solo (SOR) 017\n1 Mos Eisley (JTL) 030\n3 Cunning (SOR) 203\n3 Millennium Falcon (SOR) 155",
"title": "Han Solo Aggro"
}' --output deck.png
# Plain text body
curl -X POST https://api.swuapi.com/deck-image \
-H "Content-Type: text/plain" \
-d '1 Han Solo (SOR) 017
1 Mos Eisley (JTL) 030
3 Cunning (SOR) 203' --output deck.png
const response = await fetch('https://api.swuapi.com/deck-image', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
cards: [...],
title: 'Han Solo Aggro',
branding: { url: 'mysite.com' } // optional
})
})
const blob = await response.blob()
// Display or download the PNG image
Generate a deck image from a saved decklist. Returns PNG directly. Includes player name and tournament as subtitle. Embed in <img> tags or share directly.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
meleeId | string | Decklist ID (UUID) |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
brandUrl | string | Override branding URL |
brandName | string | Override branding name |
# Download deck image for a specific decklist
curl https://api.swuapi.com/deck-image/decklist/2261b229-5a8a-4ced-8b75-b3e200bca054 --output deck.png
# With custom branding
curl "https://api.swuapi.com/deck-image/decklist/2261b229?brandUrl=mysite.com" --output deck.png
<!-- Embed directly in HTML -->
<img src="https://api.swuapi.com/deck-image/decklist/2261b229-5a8a-4ced-8b75-b3e200bca054" />
List all meta eras. A meta era is a competitive period defined by available card pool and ban list. Set releases and mid-set bans create distinct sub-eras.
| Parameter | Type | Default | Description |
|---|---|---|---|
format |
string | all | Filter by format: premiere or limited |
curl https://api.swuapi.com/metas
curl "https://api.swuapi.com/metas?format=premiere"
{
"metas": [
{
"id": "JTL-pre-ban",
"name": "Jump to Lightspeed (pre-ban)",
"set": "JTL",
"setName": "Jump to Lightspeed",
"format": "premiere",
"start": "2025-03-14",
"end": "2025-04-11",
"isCurrent": false,
"bans": []
},
{
"id": "JTL-post-ban",
"name": "Jump to Lightspeed (post-ban)",
"set": "JTL",
"setName": "Jump to Lightspeed",
"format": "premiere",
"start": "2025-04-11",
"end": "2025-07-11",
"isCurrent": false,
"bans": [
{ "card": "Jango Fett, Concealing the Conspiracy", "cardId": "TWI_016", "action": "suspended", "effectiveDate": "2025-04-11", "format": "premiere" }
]
}
]
}
Get the current active meta era.
| Parameter | Type | Default | Description |
|---|---|---|---|
format |
string | premiere | Format: premiere or limited |
curl https://api.swuapi.com/metas/current
Get a specific meta era by ID (e.g., JTL-post-ban, SOR, TWI-limited).
curl https://api.swuapi.com/metas/JTL-post-ban
Get metas formatted for UI dropdowns. By default, when a set has sub-eras (pre-ban/post-ban), only the sub-eras are returned (not the full set entry). Sorted newest first.
| Parameter | Type | Default | Description |
|---|---|---|---|
format |
string | premiere | Format: premiere or limited |
includeFullSet |
boolean | false | Include full-set entries alongside sub-eras |
curl https://api.swuapi.com/metas/dropdown
{
"options": [
{ "id": "LAW", "name": "A Lawless Time", "isCurrent": true },
{ "id": "SEC", "name": "Secrets of Power", "isCurrent": false },
{ "id": "LOF-post-ban", "name": "Legends of the Force (post-ban)", "isCurrent": false },
{ "id": "LOF-pre-ban", "name": "Legends of the Force (pre-ban)", "isCurrent": false }
]
}
List all ban/suspension events.
curl https://api.swuapi.com/metas/bans
List all set release dates.
curl https://api.swuapi.com/metas/sets
Get the merge log for sync consumers. When entities are merged (duplicate archetypes, duplicate players), this endpoint reports what was merged and when. Consumers should poll this periodically and re-point their local references.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
since |
string | (required) | ISO 8601 timestamp — only return merges after this time |
curl "https://api.swuapi.com/merges?since=2026-03-01T00:00:00Z"
{
"merges": [
{
"entity_type": "archetype",
"from_id": 99,
"to_id": 42,
"merged_at": "2026-03-20T15:30:00.000Z"
},
{
"entity_type": "player",
"from_id": 500,
"to_id": 123,
"merged_at": "2026-03-20T16:00:00.000Z"
}
]
}
Card Object
Complete reference for all card fields.
Card Identifiers
Each card has several identifiers:
| Field | Type | Description | Unique? |
|---|---|---|---|
uuid | UUID | Stable unique identifier (ours) | Yes |
external_id | integer | Source API integer ID | Yes |
collector_number | string | Printed card code (SET_NUMBER format) | No — variants share the same number |
external_uid | string | Source API string UID | Yes |
Examples:
| Card | uuid | external_id | collector_number | variant_type |
|---|---|---|---|---|
| Standard Luke | 59e4... | 5 | SOR_005 | Standard |
| Foil Luke | a3b2... | 9745 | SOR_005 | Standard Foil |
| Hyperspace Luke | f1c7... | 981 | SOR_278 | Hyperspace |
Use uuid as the primary identifier. collector_number is not unique — foil and non-foil share the same printed number. Hyperspace cards have their own printed numbers.
Fields
| Field | Type | Description |
|---|---|---|
uuid | UUID | Stable unique identifier |
external_id | int | Source API integer ID (unique per variant) |
collector_number | string | Printed card code (SET_NUMBER format, e.g., SOR_005) |
external_uid | string | Source API string UID |
name | string | Card name |
subtitle | string | Card subtitle |
setCode | string | Set code (e.g., SOR) |
cardNumber | string | Number within set |
serialCode | string | Full serial code |
type | string | Leader, Unit, Event, Upgrade, Base |
type2 | string | Secondary type (e.g., Leader Unit) |
rarity | string | Common, Uncommon, Rare, Legendary, Special |
cost | int | Resource cost |
power | int | Attack power |
hp | int | Health points |
upgradePower | int | Power modifier (upgrades) |
upgradeHp | int | HP modifier (upgrades) |
arena | string | Ground or Space |
aspects | array | Aspect names |
aspectDuplicates | array | Duplicate aspects |
traits | array | Trait names (Rebel, Jedi, etc.) |
keywords | array | Keywords (Ambush, Sentinel, etc.) |
text | string | Card ability text |
deployBox | string | Leader deploy ability |
epicAction | string | Epic action text |
rules | string | Additional rules |
variantType | string | Standard, Hyperspace, Standard Foil, Hyperspace Foil, Showcase, Prerelease Promo, etc. |
isUnique | bool | Whether card is unique |
isLeader | bool | Is a leader card |
isBase | bool | Is a base card |
frontImageUrl | string | Front card image URL |
backImageUrl | string | Back card image URL |
thumbnailUrl | string | Thumbnail image URL |
artFrontHorizontal | bool | Front art orientation |
artBackHorizontal | bool | Back art orientation |
artist | string | Card artist name |
variants | array | strapiIds of variant cards |
variantOf | int | strapiId of original (if variant) |
reprints | array | strapiIds of reprint cards |
reprintOf | int | strapiId of original (if reprint) |
Set Codes
Known set codes and their full names.
| Code | Name |
|---|---|
SOR | Spark of Rebellion |
SHD | Shadows of the Galaxy |
TWI | Twilight of the Republic |
JTL | Jump to Lightspeed |
LOF | Legends of the Force |
SEC | Secrets of Power |
LAW | A Lawless Time |
Meta Eras
Competitive periods defined by card pool and ban list. Set releases create new eras; mid-set bans split an era into pre-ban and post-ban sub-eras.
| ID | Name | Start | End |
|---|---|---|---|
SOR | Spark of Rebellion | 2024-03-08 | 2024-07-12 |
SHD | Shadows of the Galaxy | 2024-07-12 | 2024-11-09 |
TWI | Twilight of the Republic | 2024-11-09 | 2025-03-14 |
JTL-pre-ban | Jump to Lightspeed (pre-ban) | 2025-03-14 | 2025-04-11 |
JTL-post-ban | Jump to Lightspeed (post-ban) | 2025-04-11 | 2025-07-11 |
LOF-pre-ban | Legends of the Force (pre-ban) | 2025-07-11 | 2025-09-22 |
LOF-post-ban | Legends of the Force (post-ban) | 2025-09-22 | 2025-11-07 |
SEC | Secrets of Power | 2025-11-07 | 2026-03-13 |
LAW | A Lawless Time | 2026-03-13 | (current) |
Ban Events
| Card | Action | Date |
|---|---|---|
| Jango Fett, Concealing the Conspiracy | Suspended | 2025-04-11 |
| Triple Dark Raid | Suspended | 2025-04-11 |
| DJ, Blatant Thief | Suspended | 2025-04-11 |
| Force Throw | Suspended | 2025-09-22 |
Tournament Tiers
Competitive event tiers in Star Wars: Unlimited organized play.
| Code | Name | Description |
|---|---|---|
PQ | Planetary Qualifier | Local-level competitive events (official) |
SQ | Sector Qualifier | Regional-level competitive events (official) |
RQ | Regional Qualifier | Major regional events (official) |
GC | Galactic Championship | Top-tier championship events (official) |
LCQ | Last Chance Qualifier | Last-chance entry events into championships (official) |
SS | Store Showdown | Casual store-level events (official, Asmodee-branded) |
INV | Invitational | Invitation-only competitive events (unofficial). Retired — now stored as COM. |
COM | Community | Community-run competitive events (unofficial) |
CAS | Casual Side Event | Sealed/Draft/Carbonite/On-Demand/Spotlight side events held alongside qualifier tournaments. Not official competition. |
Aspect Colors
SWU has four gameplay aspects, each with a canonical color. Heroism and Villainy are alignment aspects that modify brightness.
| Aspect | Color Name | Hex | Sample |
|---|---|---|---|
| Aggression | Red | #A83632 |
|
| Command | Green | #338D5A |
|
| Cunning | Yellow | #C5A14F |
|
| Vigilance | Blue | #4B86AA |
Alignment Modifiers
| Alignment | Effect | Use |
|---|---|---|
| Heroism | Lighter, slightly desaturated | Hero leaders (Han Solo, Sabine, Luke, etc.) |
| Villainy | Darker, more saturated | Villain leaders (Vader, Palpatine, Boba Fett, etc.) |
Base Naming Convention
| Base HP | Rarity | Naming | Example |
|---|---|---|---|
| 30 | Common | Color 30 | Red 30, Yellow 30 |
| 28 | Common | Force Color | Force Blue, Force Red |
| 27 | Common | Splash Color | Splash Green, Splash Yellow |
| varies | Rare/Special | Card name | Tarkintown, Data Vault, ECL |
Archetype Nicknames
Each archetype has a short nickname: FirstName (SET) BaseNick. Titles/ranks are stripped to get the character's name. (SET) is only included when multiple distinct leaders share the same first name.
| Full Name | Nickname | Rule |
|---|---|---|
| Han Solo, Audacious Smuggler - Red 30 | Han Red | Simple first name + base color |
| Darth Vader, Dark Lord of the Sith - Force Blue | Vader (SOR) Force Blue | Title stripped, (SET) for disambiguation |
| Grand Admiral Thrawn, Patient and Insightful - Data Vault | Thrawn (SOR) DV | Multi-word title stripped, base abbreviated |
| Grand Moff Tarkin, Oversector Governor - Tarkintown | Tarkin TT | SW title stripped, base abbreviated |
| Moff Gideon, Formidable Commander - Red 30 | Gideon Red | SW title stripped |
| Grand Inquisitor, Hunting the Jedi - Tarkintown | GI TT | Hardcoded nickname override |
| The Mandalorian, Sworn To The Creed - Red 30 | Mando Red | Special case |
| Boba Fett, Any Methods Necessary - Energy Conversion Lab | Boba (JTL) ECL | Multiple Bobas need (SET) |
Base Abbreviations in Nicknames
| Base | Nickname |
|---|---|
| Tarkintown | TT |
| Energy Conversion Lab | ECL |
| Data Vault | DV |
| Lake Country | Lake |
| Red 30 / Blue 30 / etc. | Red / Blue / etc. |
| Force Blue / Splash Green / etc. | Unchanged |
| Other rare bases | Full name |