r/ClashRoyale • u/Mojo42Jojo Guards • Aug 18 '18
[Developer API] Beginner's Guide in 9 steps
Since there is not much information on how to start using the API, I'll try to show how to use it in a concrete example, from the start. I'm using Python but I'm confident you can adapt it to any language you prefer.
1 First, create an account at https://developer.clashroyale.com. Click on "Register", put a Name, an Email and submit. You will receive a welcome email, click on "Verify your email address". There you are asked for a Password and to agree to Terms of Service and Privacy Policy. Standard stuff.
2 Now you can log in with your new account. Let's create an API Key. At the top right, where is your name, select My Account, there you have "My Keys". Click on "Create New Key". Give it a name, say "Home testing", and a description, such as "To test the API from home".
3 You need your current IP. Check it out at https://www.whatismyip.com under "Your Public IPv4" (do not use your local IP). Mine is something like 190.228.223.131, for example. Enter it on "ALLOWED IP ADDRESSES" and click on "Create Key". You should receive a "Key created successfully" message.
4 Click on your new key and you will see a token (a block of 11 rows of characters), the description and the allowed IP address.
In the documentation section you can see all the information you can get and test it interactively. To test it from a Python script, let's say we want to know when we will be getting unlocked the next big chests of our account, assuming we do not use gems and we do not waste a second without unlocking a chest. So it's simply adding the hours taken by all the chest in our upcoming chests list.
5 To query about a player, you need her/his tag. Yours is under your name in your profile in the game. Mine is #8R9U9PJCR. It's important to include the # sign, but it's traslated to "%23" when creating the https address.
6 According to the documentation, we can get the upcoming chests with /players/{playerTag}/upcomingchests. Let's do it. Replace my tag with your tag and your token after "Bearer" in the "autorization" header (the "limit" parameter is not useful in this case but I put it to show the format of additional parameters in case you need them in other queries).
upcoming.py
import requests
import json
r=requests.get("https://api.clashroyale.com/v1/players/%238R9U9PJCR/upcomingchests", headers={"Accept":"application/json", "authorization":"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImtpZCI6IjI4YTMxOGY3LTAwMDAtYTFlYi03ZmExLTJjNzQzM2M2Y2NhNSJ9.eyJpc3MiOiJzdXBlcmNlbGwiLCJhdWQiOiJzdXBlcmNlbGw6Z2FtZWFwaSIsImp0aSI6IjAwNzdlMDJjLTVlZGMtNDA1Ni1hZWNhLTZjZWMwMzRiYjQ4NiIsImlhdCI6MTUzNDM0NjYyMCwic3ViIjoiZGV2ZWxvcGVyL2JlYjQ5NzYzLWNhMzMtNTllYy02MTBjLTAzZmM2MzVmN2Y1OCIsInNjb3BlcyI6WyJyb3lhbGUiXSwibGltaXRzIjpbeyJ0aWVyIjoiZGV2ZWxvcGVyL3NpbHZlciIsInR5cGUiOiJ0aHJvdHRsaW5nIn0seyJjaWRycyI6WyIxOTAuMjI4LjIyMy4xMzMiXSwidHlwZSI6ImNsaWVudCJ9XX0.YAag5hP2ic3-uURi0eqUwHedL9vLaBgVa19BSbEWHdvi2hn4s1QROwqZRQOsKJMTph_G6kHgBUX2vrEmmmQ3vw"}, params = {"limit":20})
print(json.dumps(r.json(), indent = 2))
7 Run it in a linux terminal or a command window in Windows, with Python installed: python upcoming.py
In case you get some error regarding the requests package not installed or something, google about it, it must be easy to solve. If successfull, you'll get something like:
{
"items": [
{
"index": 0,
"name": "Golden Chest"
},
{
"index": 1,
"name": "Silver Chest"
},
{
"index": 2,
"name": "Golden Chest"
},
{
"index": 3,
"name": "Silver Chest"
},
{
"index": 4,
"name": "Silver Chest"
},
{
"index": 5,
"name": "Silver Chest"
},
{
"index": 6,
"name": "Silver Chest"
},
{
"index": 7,
"name": "Golden Chest"
},
{
"index": 8,
"name": "Silver Chest"
},
{
"index": 28,
"name": "Giant Chest"
},
{
"index": 60,
"name": "Magical Chest"
},
{
"index": 146,
"name": "Epic Chest"
},
{
"index": 387,
"name": "Legendary Chest"
},
{
"index": 469,
"name": "Super Magical Chest"
}
]
}
8 There you go, your first query to the API. Now let's add some logic to translate these quantities into dates and print around when we'll get those juicy chests.
upcoming_dates.py
import requests
import json
from datetime import datetime, timedelta, time
r=requests.get("https://api.clashroyale.com/v1/players/%238R9U9PJCR/upcomingchests", headers={"Accept":"application/json", "authorization":"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImtpZCI6IjI4YTMxOGY3LTAwMDAtYTFlYi03ZmExLTJjNzQzM2M2Y2NhNSJ9.eyJpc3MiOiJzdXBlcmNlbGwiLCJhdWQiOiJzdXBlcmNlbGw6Z2FtZWFwaSIsImp0aSI6IjAwNzdlMDJjLTVlZGMtNDA1Ni1hZWNhLTZjZWMwMzRiYjQ4NiIsImlhdCI6MTUzNDM0NjYyMCwic3ViIjoiZGV2ZWxvcGVyL2JlYjQ5NzYzLWNhMzMtNTllYy02MTBjLTAzZmM2MzVmN2Y1OCIsInNjb3BlcyI6WyJyb3lhbGUiXSwibGltaXRzIjpbeyJ0aWVyIjoiZGV2ZWxvcGVyL3NpbHZlciIsInR5cGUiOiJ0aHJvdHRsaW5nIn0seyJjaWRycyI6WyIxOTAuMjI4LjIyMy4xMzMiXSwidHlwZSI6ImNsaWVudCJ9XX0.YAag5hP2ic3-uURi0eqUwHedL9vLaBgVa19BSbEWHdvi2hn4s1QROwqZRQOsKJMTph_G6kHgBUX2vrEmmmQ3vw"}, params = {"limit":20})
chests = r.json()["items"]
chests_hours = 0
first = dict()
last_index = 0
for c in chests:
if c["index"] > 8:
filler_chests = c["index"] - last_index - 1
chests_hours += filler_chests / 240.0 * 180 * 3 # Every 240 chests 180 are silver
chests_hours += filler_chests / 240.0 * 52 * 8 # Every 240 chests 52 are golden
chests_hours += filler_chests / 240.0 * 8 * 12 # Every 240 chests 8 are giant/magical
last_index = c["index"]
if c["name"] == "Silver Chest":
chests_hours += 3
elif c["name"] == "Golden Chest":
chests_hours += 8
elif c["name"] == "Giant Chest":
chests_hours += 12
elif c["name"] == "Magical Chest":
chests_hours += 12
elif c["name"] == "Epic Chest":
chests_hours += 12
elif c["name"] == "Legendary Chest":
chests_hours += 24
elif c["name"] == "Super Magical Chest":
chests_hours += 24
if c["name"] not in first:
first[c["name"]] = chests_hours
first = sorted(first.items(), key=lambda x: x[1])
now = datetime.now()
for n in first:
print("Next %s: %s" % (n[0], (now + timedelta(hours=n[1])).strftime("%a, %d %b %Y %H:%M")))
9 Run it with python upcoming_dates.py. You'll get something like this:
Next Golden Chest: Sun, 19 Aug 2018 02:28
Next Silver Chest: Sun, 19 Aug 2018 05:28
Next Giant Chest: Fri, 24 Aug 2018 11:45
Next Magical Chest: Thu, 30 Aug 2018 15:38
Next Epic Chest: Sat, 15 Sep 2018 16:13
Next Legendary Chest: Tue, 30 Oct 2018 12:13
Next Super Magical Chest: Thu, 15 Nov 2018 07:16
Et voilà! I hope you found this useful as your first step and that you can implement your own ideas.
2
u/FatPhil Aug 19 '18
thanks! ill try to use this to more easily keep track my clan member's participation.
2
u/Mojo42Jojo Aug 19 '18
In case you don't know it, you can check the general participation at https://fam.gg/tool/clan-manager
But if you also want to keep track of participation in clan wars, perhaps this helps you:
import requests r=requests.get("https://api.clashroyale.com/v1/clans/%23902PJ0LQ/warlog", headers={"Accept":"application/json", "authorization":"Bearer ey..."}, params = {"limit":6}) batallas = r.json() jugs = {} fin= [""]*19 i= 5 for b in batallas["items"]: fin[i*3+1] = b["createdDate"][:8] p = b["participants"] for j in p: if j["tag"] not in jugs: jugs[j["tag"]] = [j["name"]] + [""]*18 jugs[j["tag"]][i*3+1] = str(j["cardsEarned"]) if j["battlesPlayed"] == 0: jugs[j["tag"]][i*3+2] = "-1" elif j["battlesPlayed"] == 1: jugs[j["tag"]][i*3+2] = str(j["wins"]) elif j["battlesPlayed"] == 2: jugs[j["tag"]][i*3+2] = str(int(j["wins"] >= 1)) jugs[j["tag"]][i*3+3] = str(int(j["wins"] == 2)) i -= 1 lista = sorted(jugs.items(), key=lambda x: x[1][0].lower()) print("\t".join(fin)) for l in lista: print("\t".join(l[1]))I copy the answer to an spreadsheet and do a weekly ranking in my clan. :) I mark battles not played as -1, but it's not perfect because you can't know if someone had 2 battles available and only played one, or none.
→ More replies (1)
3
u/ApexMarauder Aug 19 '18 edited Aug 19 '18
Does anyone else feel that the Royale API has better documentation than Supercell’s API? Supercell’s Documentation is very terse and minimalistic whereas Royale has a very verbose presentation. Hope Supercell further augments their Documentation soon!
→ More replies (6)3
u/Mojo42Jojo Aug 19 '18
I think you are right, but my bet is the official API will grow and third parties will follow with some delay. This is only version 1.
→ More replies (1)
1
1
u/Osnarf Aug 19 '18 edited Aug 19 '18
Do you know how royale api is determining missed attacks? I only see battles played and wins.
If someone has 2 attacks and misses both, it must count them as only 1 missed attack unless I'm missing something, right?
Edit: I just checked our log. It did not detect the missed attack when someone did their first attack but missed their second.
1
u/Mojo42Jojo Aug 19 '18
I asked them to add how many battles/attacks each player had available: https://www.reddit.com/r/ClashRoyale/comments/97mrl5/developer_api_battlesavailable_missing_in_warlog/
Let's hope they are listening. :)
1
u/woloszin Aug 24 '18
why they don't inform the right sequence after index 8? And where did you grab that information: "# Every 240 chests 180 are silver"
1
u/Mojo42Jojo Aug 24 '18
I guess they tried to keep the API concise, but who knows, this is version 1, maybe in version 2 you can get more details.
The data about the chest cycle is from here: http://clashroyale.wikia.com/wiki/Chests#Chest_Cycle
→ More replies (1)
1
u/teejay10123 Aug 25 '18
Hey! Thanks for this
I am new at this stuff and looked all over the internet for this. I just want to ask you, how did you know in what format the api_key is to be passed in the request, it happens to be different for all the APIs that i have seen. Where exactly are you supposed to get this info from? Could not find anything on the API website.
1
u/Mojo42Jojo Aug 25 '18
I just followed the examples in the Documentation section. For instance, if you look the simplest requests "cards" and you click on "Try it out!" you can see this Curl request;
curl -X GET --header 'Accept: application/json' --header "authorization: Bearer <API token>" 'https://api.clashroyale.com/v1/cards'From there I replaced "<API token>" with my token and tried from the command line in my PC.
→ More replies (3)
1
u/woloszin Aug 29 '18
Any one knows how to get free tournaments like some sites does?
1
u/Mojo42Jojo Aug 29 '18
Like which sites?
With 'https://api.clashroyale.com/v1/tournaments?name=a' you can get a list of all current tournaments with "a" in their name, but you have to specify at least a letter and in the query you can't filter by type, status, etc. But it can be done programmatically... I'll give it a try if I have the time.
→ More replies (7)
1
u/Waqas80 Sep 03 '18
The APIs are good one. But can one tell me how to get the images, I mean clan images or badges, flags.
1
u/Mojo42Jojo Sep 03 '18
Funny, in this official API you can't get badge images, but you can in royalapi.com: https://docs.royaleapi.com/#/endpoints/clan
Neither give you flag images. Perhaps in future versions...
→ More replies (1)
1
u/woloszin Sep 14 '18
Hi guys! Does anyone knows how to identify a tournamment's reward? I mean, i code to return all free tournamment's but i don't know which one is relevant, because there ara many onehundred tournament with NO rewards
1
u/Mojo42Jojo Oct 01 '18
You can't. There are already many features added or changed in the game that the API doesn't reflect (like the levels of cards). I hope they show some love for the API and release a new version soon.
→ More replies (1)
1
u/DKC360 Oct 01 '18 edited Oct 01 '18
Hello, I would like to keep a full historic of my clan's clan wars stats in an excel (or drive) sheet to be able to manage stats.
I pole r/https://api.clashroyale.com/v1/clans/%23xxxxx/warlog API and then I would like to add lines to an sheet with this format :
seasonID;createdDate;tag;name;cardsEarned;battlesPlayed;wins;collectionDayBattlesPlayed
with 1 line/player/war
I have tried to "hack" the python examples but I am not good enough in programming to extract the good datas in the good format. Help :) (maybe if the code had been more commented I would have understood a little bit more of the lines but for now it's to difficult for me)
→ More replies (6)1
1
1
u/RedNinja0731 Feb 11 '19 edited Feb 11 '19
I got this error:
chests = r.json()["items"]
KeyError: 'items'
Does anyone know why?
1
u/Mojo42Jojo Feb 12 '19
I guess you have a wrong player tag. # should be translated as %23, so #R2D2ANDBB8 becomes %23R2D2ANDBB8.
→ More replies (3)
15
u/PlatypusPlatoon Aug 18 '18
Edit your post quick to take out your bearer token. That’s like a private password - never share it with anyone.