Legends of Runeterra


This document will provide you with a basic understanding of the Legends of Runeterra developer resources. It is designed to help you begin exploring and developing your own tools and products for Legends of Runeterra.

Getting Started

Before starting on a product for Legends of Runeterra, there are two requirements every developer must complete:

  1. Read the general policies
  2. Register your product

Only after developers have read the policies and registered their product on the Developer Portal, are they granted a limited license to use Riot Games' intellectual property (IP) outlined in the Legal Jibber Jabber.

After you've read the policies and registered your product, it's smooth sailing from there. We suggest following our Twitter and checking our blog to receive updates and joining the Developer Discord for help from the community. The Developer Discord is full of super talented and passionate developers that often run into the same issues you have. When you ask questions in the Discord you'll likely get more people helping you and your question will help others that joined after you. We hold office hours every other Friday where members of the Discord can ask questions related to developer tools or their projects. Beyond that gl and hf. Send us an app note if you run into issues that the community couldn't help you with.

Game Policy

Use Cases

Riot analyzes two main factors when evaluating applications:

  • Is the use case good and approved?
  • Does the developer show they will deliver on that use case?

To demonstrate that your app meets the use case, you should be able to have one or more of the following:

  • Be an established brand that wants to add Riot Games to its portfolio.
  • New app that is fully functional and testable by Riot.
  • Prototype that is mostly testable by Riot.
  • Mockups where Riot can clearly see your intent and the user flow.
  • A deck that shows your ambition and intent and some of the user flow.

Riot needs to see the user flow to understand what your intended player experience is, such as account creation process, log in pipeline, or queuing up for match pipeline.

Note: All apps must include functionality requiring a player to opt-in to sharing their data. This is done on the backend through RSO.

Examples of Approved Use Cases

Approved use cases usually contain one or all of the following:

  • The app does not include scouting.
  • Aggregate data stats.
  • Tournaments (prizes cannot contain cryptocurrencies)
  • Training tools, such as tools that allow players to view their own match histories and aggregate states.
  • LFG tools.
  • Applications or sites that present a premium subscription system as monetization strategy, with the exception of sites suggesting a pay-per-win type of model.
  • Overlays that let you track your own data or known information (e.g tracking what is in your deck, or cards you have created/drawn throughout the game, or your winrate with different decks over time, or what cards your opponent has played during the game)

You must also send a link to a working site, mockup, prototype, or rendering where it is easy to understand the user flows of the tool.

Examples of Unapproved Use Cases

The following use cases will not be approved:

  • Discord Bots
  • May be considered if they are particularly well-developed and Riot sees a potential for growth.
  • Apps a small, personal audience.
  • Scouting tools.
  • Apps that do not provide a link to a site or mockup.
  • Online store tracking or updates.
  • Apps with “middle-man” type of data usage, such as an app that obtains data from our API and gives or sells it to a third-party company.
  • Blockchain apps or apps that trade in the crypto space.
  • Gambling
  • Overlays tracking what cards are in your opponent's deck before they are played

RSO Integration

All apps must request that users opt-in to sharing their personal data. To do this, your application will need to verify players using an OAuth flow. This is done through Riot Sign On (RSO) using an RSO Client.

Getting a Production Key

Before you can get started with RSO, you will need a production key. If you do not have one, please create one at developer.riotgames.com. We will contact you using the email linked to your developer account to kick off the RSO integration process.

RSO Client Creation

To create an RSO client, send us the following information:

  • Email addresses of contacts for your application.
  • Name of your company/service.
  • Logo for your company/service.
    • The logo should scale well between 275x275 down to 60x60. We typically suggest images in the SVG format. The logo will be displayed on light and dark backgrounds.
  • URL for your privacy policy.
  • URL for your Terms of Service.
  • Redirect URLs.
    • Your redirect URIs cannot be direct IP addresses. HTTPS is required.
    • Your redirect URIs cannot include localhost. Instead, for local development, you can use something like "http://local.safe.urlgoeshere.com/account/connect/riotgames/oauth-callback" and add an entry to your local machine's host file for "local.safe.urlgoeshere.com".
  • A list of any URLs you'd like RSO to redirect the players to after they've completed their login.
    • Typically this is a callback URL (e.g., example.com/oauth-callback) that you'll use to gather information about the player who completed the login.
  • Post Logout Redirect URIs.
    • A list of any URLs you'd like RSO to redirect the players to after they've logged out.
  • Preferred ClientID
    • A unique name for your product without punctuation or spaces.
  • A list of games you'll need access to.

Direct players to login at this link: https://auth.riotgames.com/authorize?client_id=&redirect_uri=&response_type=code&scope=openid+offline_access.

After logging in, players are redirected back to the redirect_uri you specified. See Implementing Riot Sign On and Example RSO Node App for information about how to integrate with RSO and to view a sample Node web server that implements the example.

Your RSO client has access to endpoints that will allow you to identify who logged in.

For Legends of Runeterra, you will use /riot/account/v1/accounts/me:

curl --location --request GET 'https://americas.api.riotgames.com/riot/account/v1/accounts/me' --header 'Authorization: Bearer {accessToken}'
curl --location --request GET 'https://europe.api.riotgames.com/riot/account/v1/accounts/me' --header 'Authorization: Bearer {accessToken}' 
curl --location --request GET 'https://asia.api.riotgames.com/riot/account/v1/accounts/me' --header 'Authorization: Bearer {accessToken}' 

The data return from each cluster is identical. We recommend using the cluster closest to your servers.

Data Dragon

Legends of Runeterra Data Dragon (not to be confused with League of Legends Data Dragon) is the name of the static data product that will host both game assets and data for community use in media or product development. Assets and data are made available over the internet in the format described below, and are updated in tandem with game releases so the community can update their products with the latest and greatest data. Legends of Runeterra static data is split into two bundles; core bundles and set bundles.

Core Bundles

The core bundles contain foundational assets and data that are shared across cards in all sets. This includes information like factions, icons, queues, rules, etc. Core bundles are available over the internet at the following urls:



The core bundle once extracted will have the following structure:

├─ README.md
├─ metadata.json
└─ {locale}/
   ├─ data/
   │  └─ globals-{locale}.json
   └─ img/
      └─ regions/
         └─ icon_demacia.png

The metadata.json file contains data related to the locale and version of the bundle.

The global.json file contains sets of values that are reused throughout various cards. This includes keywords, rarities, regions (otherwise known as factions), spell speeds, and card types. There are two fields are paired with each other; name and nameRef. The name field will return a localized value, while the nameRef field will return a reference value that remains consistent across every locale.

  "keywords": [
      "name": "Frostbite", // localized
      "nameRef": "Frostbite",
  "rarities": [...],
  "regions": [...],
  "spellSpeeds": [...],
  "types": [...]

Set Bundles

The set bundles contain assets and data for cards released in a specific set. Set bundles are available in two versions; full and lite. The full set bundle contains the card art, alternative art, and full size illustrations for each card. The lite version only contains the card art and the alternative art making the lite version significantly smaller in size. Set bundles are available over the internet at the following urls:

[set1 full] https://dd.b.pvp.net/latest/set1-en_us.zip
[set1 lite] https://dd.b.pvp.net/latest/set1-lite-en_us.zip

[set2 full] https://dd.b.pvp.net/latest/set2-en_us.zip
[set2 lite] https://dd.b.pvp.net/latest/set2-lite-en_us.zip

[set3 full] https://dd.b.pvp.net/latest/set3-en_us.zip
[set3 lite] https://dd.b.pvp.net/latest/set3-lite-en_us.zip

[set4 full] https://dd.b.pvp.net/latest/set4-en_us.zip
[set4 lite] https://dd.b.pvp.net/latest/set4-lite-en_us.zip

[set5 full] https://dd.b.pvp.net/latest/set5-en_us.zip
[set5 lite] https://dd.b.pvp.net/latest/set5-lite-en_us.zip

[set6 full] https://dd.b.pvp.net/latest/set6-en_us.zip
[set6 lite] https://dd.b.pvp.net/latest/set6-lite-en_us.zip

[set6cde full] https://dd.b.pvp.net/latest/set6cde-en_us.zip
[set6cde lite] https://dd.b.pvp.net/latest/set6cde-lite-en_us.zip

[set1 full] https://dd.b.pvp.net/1_0_0/set1-en_us.zip
[set1 lite] https://dd.b.pvp.net/1_0_0/set1-lite-en_us.zip

[set2 full] https://dd.b.pvp.net/1_0_0/set2-en_us.zip
[set2 lite] https://dd.b.pvp.net/1_0_0/set2-lite-en_us.zip

[set3 full] https://dd.b.pvp.net/1_8_0/set3-en_us.zip
[set3 lite] https://dd.b.pvp.net/1_8_0/set3-lite-en_us.zip

[set4 full] https://dd.b.pvp.net/2_3_0/set4-en_us.zip
[set4 lite] https://dd.b.pvp.net/2_3_0/set4-lite-en_us.zip

[set5 full] https://dd.b.pvp.net/2_14_0/set5-en_us.zip
[set5 lite] https://dd.b.pvp.net/2_14_0/set5-lite-en_us.zip

[set6cde full] https://dd.b.pvp.net/3_17_0/set6cde-en_us.zip
[set6cde lite] https://dd.b.pvp.net/3_17_0/set6cde-lite-en_us.zip

The set bundle once extracted will have the structure below.

├── README.md
├── metadata.json
└── {locale}/
    ├── data/
    │   └── set1-{locale}.json
    └── img/
        └── cards/
            ├── 01DE001.png
            ├── 01DE001-full.png (not included in lite bundles)
            ├── 01DE001-alt.png
            └── 01DE001-alt-full.png (not included in lite bundles)

The metadata.json file contains data related to the locale and version of the bundle.

The set.json file contains data related to cards in the specific set. For each card, information is provided on the card's assets, associated cards, attack, health, cost, description, flavor text, name, code, keywords, rarity, type, and subtype.

    "associatedCards": [],
    "associatedCardRefs": [
    "assets": [
        "gameAbsolutePath": "http://dd.b.pvp.net/1_0_0/set1/en_us/img/cards/01FR009.png",
        "fullAbsolutePath": "http://dd.b.pvp.net/1_0_0/set1/en_us/img/cards/01FR009-full.png"
    "region": "Freljord",
    "regionRef": "Freljord",
    "attack": 0,
    "cost": 3,
    "health": 5,
    "description": "",
    "descriptionRaw": "",
    "levelupDescription": "I've survived 10 total damage<style=Variable></style>.",
    "levelupDescriptionRaw": "I've survived 10 total damage.",
    "flavorText": "“Papa, tell the one about Braum and his door!”\n\"Or when his fall split a mountain in two!\"\n\"Oh! Whattabout when he saved the tavern from the rampaging yeti?!\"",
    "artistName": "SIXMOREVODKA",
    "name": "Braum",
    "cardCode": "01FR009",
    "keywords": [
    "keywordRefs": [
    "spellSpeed": "",
    "spellSpeedRef": "",
    "rarity": "Champion",
    "rarityRef": "Champion",
    "subtype": "",
    "supertype": "Champion",
    "type": "Unit",
    "collectible": true

Paired Fields
Fields are often paired with a reference field, similar to those in the global.json in the core bundle. As an example, the keywords field is paired with a keywordsRef field. The keywords field will return localized values, while the keywordsRef field will return reference values that remains consistent across every locale. Some of these fields contain lists of values and while these lists are not ordered the position in the list should remain consistent with the paired field (i.e., the first element in the keywords field will be paired with the first element in they keywordsRef field).

Card Images
Each card in the full set bundle has at least two image files:

  • The card render (e.g., 01DE001.png) is an image of the full card including its stats and text and frame, in the relevant locale. These images are 768x1024 pixels.
  • The card illustration (e.g., 01DE001-full.png) is the full card art, without stats or text or a card frame. These images are 1024x1024 pixels for spells, and 2048x1024 pixels for all other cards.

In some cases, cards may have an alternative version of card art available in addition:

  • The card alt render (e.g., 01DE001-alt.png) is an image of the full card as described above, but with the alternative art.
  • The card alt illustration (e.g., 01DE001-alt-full.png) is the full card art as described above, but with the alternative art.

The card images are hosted at the urls listed in the assets field of the set.json:


There are separate core and set bundles for each supported language meaning these bundles will need to be fetched separately for each language you wish to support in your product. Below is a list of the supported languages.

Code Language
de_de German (Germany)
en_us English (United States)
es_es Spanish (Spain)
es_mx Spanish (Mexico)
fr_fr French (France)
it_it Italian (Italy)
ja_jp Japanese (Japan)
ko_kr Korean (Korea)
pl_pl Polish (Poland)
pt_br Portuguese (Brazil)
th_th Thai (Thailand)
tr_tr Turkish (Turkey)
ru_ru Russian (Russia)
zh_tw Chinese (Taiwan)

Deck Codes

The Legends of Runeterra game client allows for players to encode/decode Legends of Runeterra deck to/from a simple string so that decks can be shared between players. Below is an example of a code for an Demacia/Freljord deck.


We have a public C# library on GitHub to demonstrate how to generate and parse a deck codes and will be reviewing pull requests if community would like to contribute. If members of the community would like to create implementations in other languages, we'd be happy to reference those implementations in the README.

Game Client API

The Legends of Runeterra game client exposes a collection of endpoints that can be used to describe the deck being used by the player in an active game, the positions of the cards on the board, and the result of the player's most recently completed game.

The game client API is enabled locally on the player's computer via port 21337 by default. If the player chooses, this API can be disabled and the port may be adjusted in the settings menu.

Active Deck

The static-decklist endpoint can be used to describe the player's current deck in an active game. The request returns the deck code and a map of each card in the form of a card code and the count of each card in the deck. As the name of the endpoint suggests, this response remains static even after cards in the deck have been played. Below is an example of a response from this endpoint.


  "DeckCode": "DECKCODE",
  "CardsInDeck": {
    "01DE000": 1,
    "01DE001": 2,

If a request is made to the static-decklist endpoint while the player is not in an active game, the endpoint will return null values, seen below.

  "DeckCode": null,
  "CardsInDeck": null

Card Positions

The positional-rectangles endpoint can be used to determine the position of the cards in the collection, deck builderand active games. Unlike the static-decklist endpoint, the positional-rectangles endpoint will return the position of the cards at the time of the request. The response time of this endpoint will vary by computer, however we suggest polling this endpoint no more than once per second. Below is an example of a response from this endpoint.


  "PlayerName": "Riot Tuxedo",
  "OpponentName": "Riot Gene",
  "GameState": "InProgress",
  "Screen": {
    "ScreenWidth": 1920,
    "ScreenHeight": 1200
  "Rectangles": [
      "CardID": 0,
      "CardCode": "01DE001",
      "TopLeftX": 800,
      "TopLeftY": 900,
      "Width": 252,
      "Height": 373,
      "LocalPlayer": true

As mentioned before, the positional-rectangles endpoint can be used in the collection, deck builder and active games. In the collection view and deck builder the GameState will return Menus. If an active game is in progress, the GameState will return InProgress. If a request is made to the positional-rectangles endpoint while no cards visible, Rectangles will return an empty list, seen below.

  "PlayerName": null,
  "OpponentName": null,
  "GameState": "Menus",
  "Screen": {
    "ScreenWidth": 1,
    "ScreenHeight": 1
  "Rectangles": []

The TopLeftX and TopLeftY fields indicate the position of the top left corner of the card relative to the bottom left corner of the game client. In the example above, the top left corner of the card would be 900 pixels from the bottom edge of the client and 800 pixels from the left edge of the client.
The Width and Height fields indicate the dimensions of the card itself.
LocalPlayer is a boolean field which returns true if the particular card belongs to the local player and false if the card belongs to an opponent in-game.

Game Result

A request to the game-result endpoint can be made to determine the result of the player's most recently completed game. The request returns an int for GameID and a boolean for LocalPlayerWon. The GameID resets every time the client restarts and is incremented after a game is completed. The GameID isn't associated with any other source of data. Below is an example of a response from this endpoint.


    "GameID": 0,
    "LocalPlayerWon": true