Magic The Gathering Card API

Franklin Navarro
Strategio
Published in
6 min readMay 13, 2022
A big ol’ pile of cardboard

Hi all! Today I’ll be continuing my series on things I’ve learned in the Strategio simulator, and this time with a game near and dear to my heart. If you’re unfamiliar, Magic the Gathering is a trading card game that’s been around for a long time (the game turns 30 years old in August of 2023). Over all that time the game’s creators, Wizards of the Coast, have been consistently releasing somewhere between 2 and 4 major expansions to the game each year since. Add in supplementary releases, alternate art printings, promotional cards, etc., and you end up with a lot of cards. A cursory google search shows a whopping 49,998 unique English cards at time of writing, and that doesn’t even include foil or foreign language printings.

Although the pool of cards that are actually used in regular play is much smaller, that’s still a mountain of cardboard that needs to be sorted through when building decks. If this sounds like a problem that could be solved with a massive database, then you’re right. Wizards of the Coast maintains a large database called Gatherer, where you can look up any card ever printed using a dizzying array of search filters. Unfortunately, Gatherer itself has no publicly available form of programmatic access, but several independent teams have worked to create REST APIs that fill this purpose. Scryfall is the largest and most popular, includes price data from major card markets, and is used for a number of Reddit and Discord bots. However, we only care about the cards themselves, so today we’ll be working with the MTG API built by the team at magicthegathering.io. As we go, I’ll be showing off some IntelliJ and Maven basics I’ve learned at Strategio.

I worked on this project using WSL and IntelliJ on Windows, as it has a nice bit of integration with WSL’s file system.

The first step is to create a new Maven project. Here, I just used the quickstart archetype for simplicity’s sake.

Next, pop open your pom.xml file and add the dependency for the MTG API.

Great, now we’re ready to take a look at the API itself. The main class we’ll be using to make API calls is CardAPI, which can request a single card using its collector number (unique to each English card) or its multiverse ID (unique to each printing of each card), or get a list of up to 100 cards based on the many search filters I mentioned in the above paragraph. You can look at the full array of search filters available in the docs here, but this example I’ll just show how to search by name.

First order of business is to create the list of cards, the Scanner to read from the terminal, and the class to print the card. For this project I made a custom class CardPrinter (which we’ll take a look at later) that only prints the stuff we care about, as Card’s toString() will print a ton of information including errata rules text, tournament rulings, and foreign language names.

Next, we need to take input from the user:

We prepend “name=” to indicate that we’re filtering by name. Now we’ll use this filter to make the API call, and try to handle any exceptions thrown because of network issues/rate limits. CardAPI.getAllCards() takes a list of Strings as its filters, so we turned our one filter into a list.

Finally, we’ll print out each card in the list using our CardPrinter.

You may notice that we’re only printing cards whose multiverseID doesn’t equal -1. This is to avoid versions of cards on Magic Arena, one of Magic’s online clients, a few of which have altered rules text.

If you’re familiar with Magic, you probably know that card text and formatting has quite a bit of variety to it based on what type of card it is. To deal with this, I made some custom code to print cards in a readable way.

This block basically prints things that all cards have (name, set, types) and uses an inline boolean to check whether or not it should print things like power & toughness or planeswalker loyalty.

Alright, everything should be in order for us to search our first card! Let’s search up Teferi, Time Raveler, the current and former bane of several formats in Magic.

copyright Wizards of the Coast

Run the program, then type the name into the console.

50 results? Teferi is a pretty popular character in Magic, and is referenced in the names of a lot of cards. CardAPI’s search doesn’t match exact strings and is pretty generous in including anything that matches keywords, so don’t be surprised if your search for Knight of the Ebon Legion gives you some of the 108 or so cards with “Knight” in their name. As you write code using the API, keep in mind that you’ll probably have to add code to pare down results. In case you were wondering, here’s the output for Teferi, Time Raveler.

Instead, why don’t we look for a card that doesn’t share words in its name with a bunch of other cards. How about Lhurgoyf?

Let’s take a look at the output:

There’s definitely only one card with “Lhurgoyf” in its name, so how are there still 6 results? If you look closely, you can see that these bottom two results are different printings, the first printed in Commander 2011, and the second the original printing in Ice Age. These two have different multiverse IDs, and therefore will show up as separate results in our query. In implementing the API, you may also want to combine different printings of the same card when displaying them.

Thanks for reading about the basics of this API, and I hope I got you at least a bit interested in both Java programming and Magic. I’d like to continue to work on MTGcardgatherer to add the features mentioned above, as well as support for flip and dual-faced modal cards. This code is not currently public on GitHub, but if I do make it available I’ll link it here.

--

--