Legends of Runeterra

Developer API Policy

Before you begin, read through the General and Game Policies, Terms of Use and Legal Notices. Developers must adhere to policy changes as they arise.

Registration

If your product serves players, you must register it with us regardless of whether or not your product uses official documented APIs. You must make sure its description and metadata are kept up to date with the current version of your product.

Monetization

To monetize your product, you must abide by the following:

  • Your product cannot feature betting or gambling functionality.
  • Your product must be registered on the Developer Portal and your product status is either Approved or Acknowledged.
  • You must have a free tier of access for players, which may include advertising.
  • Your content must be transformative if you are charging players for it.
    • What is transformative?
      • Was value added to the original by creating new information, new aesthetics, new insights, and understandings? If so, then it was transformative.
    • Acceptable ways to charge players are:
      • Subscriptions, donations, or crowdfunding.
      • Entry fees for tournaments.
      • Currencies that cannot be exchanged back into fiat.
    • Your monetization cannot gouge players or be unfair, as decided by Riot.

If you are unsure if your monetization platform is acceptable, contact us through the Developer Portal.

Security

You must adhere to the following security policies:

  • Do not share your Riot Games account information with anyone.
  • Do not use a Production API key to run multiple projects. You may only have one product per key.
  • Use SSL/HTTPS when accessing the APIs so your API key is kept safe.
  • Your API key may not be included in your code, especially if you plan on distributing a binary.
    • This key should only be shared with your teammates. If you need to share an API key for your product with teammates, make sure your product is owned by a group in the Developer portal. Add additional accounts to that account as needed.

Game Integrity

  • Products cannot alter the goal of the game (i.e. Destroy the Nexus).
  • Products cannot create an unfair advantage for players, like a cheating program or giving some players an advantage that others would not otherwise have.
  • Products should increase, and not decrease the diversity of game decisions (builds, compositions, characters, decks).
  • Products should not remove game decisions, but may highlight decisions that are important and give multiple choices to help players make good decisions.
  • Products cannot create alternatives for official skill ranking systems such as the ranked ladder. Prohibited alternatives include MMR or ELO calculators.
  • Products cannot identify or analyze players who are deliberately hidden by the game.

Tournament Policies

  • Tournaments must:
    • Follow all monetization policies above.
    • Allot at least 70% of the entry fees to the prize pool.
    • Win conditions must be fair and transparent to players (we determine fair).
    • Must have at least 20 participants.
    • Not include any gambling.
  • If you are a tournament organizer operating in the US or Canada please refer to, and adhere to, these North American tournament organizer policies.
  • If you are a tournament organizer operating in Oceania please refer to, and adhere to, these Oceanic tournament organizer policies.
  • If you are a tournament organizer operating in Europe, please refer to, and adhere to, these European tournament organizer policies.

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 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 express 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, login pipeline, or queuing up for match pipeline.

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.

Note: All apps must include functionality requiring a player to opt-in to sharing their data. This is done through RSO integration, as well as a disclaimer within your app that account linking makes player data public.

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. For example, 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.

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

RSO or Riot Sign On, allows players to safely link their Riot Account to other applications. This access is only available to developers with Production Level API Keys.

Getting a Production Key

Before you can get started with RSO, you will need a production key. If you do not have one, please request one at developer.riotgames.com after reading through our policies. If approved, we will contact you in the developer portal app messaging to kick off the RSO integration process.

Implementing RSO

Players should be directed 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 Sample 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 accounts data returned 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 static data product that hosts 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:

Latest

https://dd.b.pvp.net/latest/core-en_us.zip

Versioned

https://dd.b.pvp.net/1_0_0/core-en_us.zip

Path of Champions Content

https://dd.b.pvp.net/latest/adventure-en_us.zip

The core bundle once extracted will have the following structure:

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

metadata.json

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

globals.json

global.json 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:

Latest

[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

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

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

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

Versioned

[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/4_2_0/set6cde-en_us.zip
[set6cde lite] https://dd.b.pvp.net/4_2_0/set6cde-lite-en_us.zip

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

[set7b full] https://dd.b.pvp.net/4_6_0/set7b-en_us.zip
[set7b lite] https://dd.b.pvp.net/4_6_0/set7b-lite-en_us.zip

[set8b full] https://dd.b.pvp.net/4_9_0/set8-en_us.zip
[set8b lite] https://dd.b.pvp.net/4_9_0/set8-lite-en_us.zip

[set9 full] https://dd.b.pvp.net/5_4_0/set9-en_us.zip
[set9 lite] https://dd.b.pvp.net/5_4_0/set9-lite-en_us.zip

The set bundle once extracted will have the structure below.

set1-{locale}/
├── COPYRIGHT
├── 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)

metadata.json

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

set.json

set.json 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": [
      "01FR009T1",
      "01FR009T2",
      "01FR053"
    ],
    "assets": [
      {
        "gameAbsolutePath": "https://dd.b.pvp.net/1_0_0/set1/en_us/img/cards/01FR009.png",
        "fullAbsolutePath": "https://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": [
      "Challenger",
      "Regeneration"
    ],
    "keywordRefs": [
      "Challenger",
      "Regeneration"
    ],
    "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 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. For example, 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, such as 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, such as 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, such as 01DE001-alt.png, is an image of the full card as described above, but with the alternative art.
  • The card alt illustration, such as 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:
https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001.png

Languages

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. The following languages are supported:

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)

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 using port 21337 by default. If the player chooses, this API can be disabled and the port may be adjusted in the settings menu.

NOTE: We provide no guarantees of full documentation, service uptime, or change communication for unsupported services. This team does not own any components of the underlying services, and will not offer additional support related to them.

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:

GET http://127.0.0.1:{port}/static-decklist

{
  "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:

{
  "DeckCode": null,
  "CardsInDeck": null
}

Card Positions

The positional-rectangles endpoint can be used to determine the position of the cards in the collection, deck builder, and active games. Unlike the static-decklist endpoint, the positional-rectangles endpoint returns the position of the cards at the time of the request. The response time of this endpoint will vary by computer, but you should poll this endpoint no more than once per second. Below is an example of a response from this endpoint:

GET http://127.0.0.1:{port}/positional-rectangles

{
  "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
    },
    ...
  ]
}

GameState
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:

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

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 is 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 is not associated with any other source of data. Below is an example of a response from this endpoint:

GET http://127.0.0.1:{port}/game-result

{
    "GameID": 0,
    "LocalPlayerWon": true
}

Deck Codes

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

CEAAEBYBAEDRMGREFYZDKCABAABQMCYSCQNB2JYCAQAQABYMFIWAMAIBBEKCAIRHFE

The public LoR DeckCodes C# library demonstrates how to generate and parse a deck codes. We will review pull requests if members of the community contribute. If members of the community would like to create implementations in other languages, we are happy to reference those implementations in the README.

Getting Help and Staying Up-to-date

If you run into any difficulties or are having technical issues, please join Developer Discord for support. Follow our Twitter for the latest updates.