Resource Usage Stats API

fingerprint

Banned deucer.
Hi

I wrote an API to easily fetch usage stats for a specific pokemon in a specific tier. The API has 2 supported endpoints:

Potential uses:
- discord bots
- PS bots
- userscripts

Code:
/tier/pokemon
Returns the most recent usage stats for the specified pokemon in the specified tier.

EX:

https://smogon-usage-stats.herokuapp.com/gen8ou/clefable

JSON:
{"tier":"gen8ou","pokemon":"Clefable","rank":"2","usage":"34.02292%","raw":"675606","abilities":{"Magic Guard":"89.781%","Unaware":"10.082%","Cute Charm":"0.137%"},"items":{"Leftovers":"68.880%","Life Orb":"25.773%","Sticky Barb":"3.187%","Other":"2.160%"},"spreads":{"Calm":{"252/0/0/4/252/0":"10.994%","252/0/160/0/96/0":"9.822%","252/0/4/0/252/0":"9.636%"},"Bold":{"252/0/252/0/4/0":"6.645%","252/0/252/4/0/0":"3.192%"},"Modest":{"196/0/0/252/0/60":"3.693%"},"Other":"56.019%"},"moves":{"Moonblast":"99.135%","Wish":"51.661%","Protect":"43.770%","Soft-Boiled":"36.336%","Flamethrower":"28.594%","Calm Mind":"21.283%","Stealth Rock":"20.867%","Thunder Wave":"20.573%","Thunderbolt":"17.715%","Aromatherapy":"15.313%","Moonlight":"13.631%","Knock Off":"4.031%","Trick":"3.970%","Heal Bell":"3.877%","Other":"19.245%"},"teammates":{"Corviknight":"+16.465%","Seismitoad":"+7.038%","Toxapex":"+6.647%","Rotom-Heat":"+5.679%","Hydreigon":"+4.064%","Mandibuzz":"+2.766%","Hippowdon":"+2.000%","Conkeldurr":"+1.937%","Kyurem":"+1.809%","Gastrodon":"+1.382%","Rotom-Wash":"+0.919%","Tyranitar":"+0.848%"},"checks":{"Bisharp":{"ko":"24.7%","switched":"61.0%"},"Gengar":{"ko":"15.4%","switched":"67.6%"},"Excadrill":{"ko":"9.8%","switched":"70.1%"},"Centiskorch":{"ko":"7.2%","switched":"82.2%"},"Aegislash":{"ko":"12.9%","switched":"64.3%"},"Durant":{"ko":"27.5%","switched":"63.4%"},"Venusaur":{"ko":"30.3%","switched":"49.8%"},"Diggersby":{"ko":"20.4%","switched":"60.4%"},"Melmetal":{"ko":"10.5%","switched":"64.8%"},"Dracovish":{"ko":"29.8%","switched":"41.1%"},"Copperajah":{"ko":"12.9%","switched":"70.6%"},"Salazzle":{"ko":"7.6%","switched":"73.1%"}}}
Tier: Tier that was provided
Pokemon: Pokemon that was provided
Rank: Ordinal ranking of the pokemon based on usage
Usage: Usage percentage
Raw: # of times the pokemon was used.
Abilities: Usage percentage for each ability the pokemon has.
Items: Item usage percentage for the pokemon specified
Spreads: usage percentage of a variety of EV spreads based on nature
Teammates: Typical teammates associated with this pokemon
Checks: Typically unfavored pokemon and the percentage of times the pokemon switches out / is KO'ed by each specific check


For more specific data grabbing:

Code:
/year/month/tier/rank/pokemon
important note about "rank": generally, it's 1630 for all tiers but OU, where its 1695. (be mindful of this when making requests)

Example Usage


JavaScript:
'use strict';

const https = require('https');

https.get('https://smogon-usage-stats.herokuapp.com/2019/12/gen8ou/1695/dragapult', res => {
    let data = '';
    res.on('data', chunk => {
        data += chunk;
    }).on('end', () => {
        console.log(data); //  {"tier":"gen8ou","pokemon":"Dragapult","rank":"1","usage":"39.26222%","raw":"1932908","abilities":{"Infiltrator":"85.399%","Clear Body":"11.368%","Cursed Body":"3.232%"},"items":{"Choice Specs":"43.190%","Leftovers":"20.751%","Life Orb":"11.180%","Choice Scarf":"10.954%","Choice Band":"7.178%","Expert Belt":"2.254%","Other":"4.493%"},"spreads":{"Timid":{"0/0/0/252/4/252":"32.522%","4/0/0/252/0/252":"3.119%"},"Modest":{"0/0/0/252/4/252":"11.529%","0/0/4/252/0/252":"3.231%"},"Adamant":{"0/252/0/0/4/252":"8.876%"},"Jolly":{"0/252/0/0/4/252":"6.801%"},"Other":"33.922%"},"moves":{"Shadow Ball":"57.759%","Draco Meteor":"57.146%","Fire Blast":"41.973%","U-turn":"37.239%","Thunderbolt":"35.738%","Dragon Darts":"29.379%","Phantom Force":"25.232%","Substitute":"21.532%","Dragon Dance":"18.610%","Flamethrower":"17.028%","Will-O-Wisp":"12.074%","Hex":"11.850%","Sucker Punch":"10.086%","Disable":"9.212%","Other":"15.141%"},"teammates":{"Bisharp":"+2.420%","Corviknight":"+1.474%","Excadrill":"+1.135%","Ditto":"+1.021%","Obstagoon":"+0.915%","Darmanitan-Galar":"+0.809%","Rotom-Wash":"+0.801%","Cloyster":"+0.768%","Clefable":"+0.521%"},"checks":{"Grimmsnarl":{"ko":"13.5%","switched":"62.4%"},"Sylveon":{"ko":"14.1%","switched":"61.4%"},"Bisharp":{"ko":"28.2%","switched":"44.8%"},"Mimikyu":{"ko":"31.3%","switched":"40.6%"},"Tyranitar":{"ko":"14.2%","switched":"51.2%"},"Clefable":{"ko":"17.5%","switched":"43.5%"},"Ditto":{"ko":"22.8%","switched":"34.0%"},"Alcremie":{"ko":"13.1%","switched":"61.5%"}}}
    });
});
;
HOSTED HERE: https://smogon-usage-stats.herokuapp.com/
 
Last edited:

DaWoblefet

Demonstrably so
is a Battle Simulator Administratoris a Community Leaderis a Programmeris a Top Researcheris a Top Tiering Contributoris a Social Media Contributor Alumnus
PS Admin
Is data from the moveset folder obtainable via this API? For example, I could make the request to https://smogon-usage-stats.herokuapp.com/2020/02/gen8vgc2020/1760/togekiss for the rank at which Togekiss exists in that tier for that month, but is there a way to retrieve data from moveset? I would love to implement a .usage pokemon command for the VGC room bot taking advantage of moveset data and displaying it in a fancy way via an htmlbox, but I don't think I have much use for the rank and usage % data by itself.
 

fingerprint

Banned deucer.
Is data from the moveset folder obtainable via this API? For example, I could make the request to https://smogon-usage-stats.herokuapp.com/2020/02/gen8vgc2020/1760/togekiss for the rank at which Togekiss exists in that tier for that month, but is there a way to retrieve data from moveset? I would love to implement a .usage pokemon command for the VGC room bot taking advantage of moveset data and displaying it in a fancy way via an htmlbox, but I don't think I have much use for the rank and usage % data by itself.
not as of right now but i definitely see the use for that! ill work on adding that as we speak and it should be added by the end of today. Thank you for the suggestion! :)
 
So im new to api's and such and i was wondering if you can walk me through and help me get started using this api
The owner of this API is banned from Smogon, which is a shame. However, I might be able to help you use this (at least with node.js).

APIs are just webpages with absolutely nothing on them except data, so if we can find away to get this data and parse it, we can do whatever we want with it. There are lots of different methods to do this, the most common one is the basic request module, which I'll give an example of in a bit. There are lots of others, this is the most basic.

APIs normally have different routes for different bits of data, let's take this API as an example. Look at the URL:

https://smogon-usage-stats.herokuapp.com/2019/12/gen8ou/1695/dragapult

Blue - the domain where the API lives.
Red - the path to get to the data we want.

The path is configurable to get the precise data you need. For example: I could edit the 'dragapult' to 'clefable' to get the usage stats for Clefable or change the 'gen8ou' to 'gen8lc' to get the data for Little Cup. APIs normally are documented which shows where you can find all the data.

Now we get onto actually using it. Once we have the URL we need we can simply use the request module to fetch it, then do whatever we want with it in the callback. Example:

Code:
// Make sure you run npm install before executing.

const request = require('request');

require('https://smogon-usage-stats.herokuapp.com/2019/12/gen8ou/1695/dragapult', (error, response, body) => {
if (error) return console.log(JSON.stringify(error));
let JSONresponse = JSON.parse(body); // You now have your parsed data, ready to do whatever you want.
console.log(JSONresponse.raw);
})
Sorry for lack of indentations.

So there you have my brief guide to basic APIs. Sometimes APIs have an extra part of the URL, the parameters, but since that's not here I won't worry about it.
 
The owner of this API is banned from Smogon, which is a shame. However, I might be able to help you use this (at least with node.js).

APIs are just webpages with absolutely nothing on them except data, so if we can find away to get this data and parse it, we can do whatever we want with it. There are lots of different methods to do this, the most common one is the basic request module, which I'll give an example of in a bit. There are lots of others, this is the most basic.

APIs normally have different routes for different bits of data, let's take this API as an example. Look at the URL:

https://smogon-usage-stats.herokuapp.com/2019/12/gen8ou/1695/dragapult

Blue - the domain where the API lives.
Red - the path to get to the data we want.

The path is configurable to get the precise data you need. For example: I could edit the 'dragapult' to 'clefable' to get the usage stats for Clefable or change the 'gen8ou' to 'gen8lc' to get the data for Little Cup. APIs normally are documented which shows where you can find all the data.

Now we get onto actually using it. Once we have the URL we need we can simply use the request module to fetch it, then do whatever we want with it in the callback. Example:

Code:
// Make sure you run npm install before executing.

const request = require('request');

require('https://smogon-usage-stats.herokuapp.com/2019/12/gen8ou/1695/dragapult', (error, response, body) => {
if (error) return console.log(JSON.stringify(error));
let JSONresponse = JSON.parse(body); // You now have your parsed data, ready to do whatever you want.
console.log(JSONresponse.raw);
})
Sorry for lack of indentations.

So there you have my brief guide to basic APIs. Sometimes APIs have an extra part of the URL, the parameters, but since that's not here I won't worry about it.
No this is great. I know how to code but i forgot to run npm install to make it work
 
hmm so i made a python thing that can pull and scrape the usage stats pages and neaten them up and push to a sql server, (or i guess any database, but im a sql truther), I also have no idea how to deploy a proper library (but if someone wants to hold my hand that would be fabulous!) I figure from there I (or someone) could create a usable API. it doesn't have moves data or teammates data yet, which is a real shame, but it doesn't seem impossible to re-create.

although, after googling while writing this post to see if i could find the former user's git repo, I did discover this by Antar edit: FelixRilling:

https://github.com/FelixRilling/smogon-usage-fetch

and here's the npm page

https://www.npmjs.com/package/smogon-usage-fetch?activeTab=readme

maybe a good substitute? i havent used it yet, but im making a teambuilding-adjacent app and wanted to get usage data in there, and noticed that OPs has not been updated since April 20, well before the home updates so a lot of things are missing.

edit: here is the link to my python repo. feel free to take it and run with it, but I'll probably start working on it again to rebuild (at least for my personal use) something https://github.com/Stu-Gotz/smog_usage_stats
 
Last edited:
So I was playing with the "smogon-usage-fetch" api and there's a couple of changes to take note of

the README is not correct. You will most likely need to use a proxy to bypass CORS. I don't know if that violates any smogon policy, if it does please let me know and ill remove this.

Code:
const client = new SmogonApiClient({
    customBaseUrl: new URL("https://my-proxy/"),
});

change to:

const client = new SmogonApiClient({
    baseUrl: new URL("https://my-proxy/https://www.smogon.com/stats"),
});
EDIT: actually this API is wierd, and kind of bad compared to OPs, sadly.

dont import the SmogonApiClientConfig module as it says in the README, it's not used. Also, Antar has a similar type library for python on github. I haven't tried it out, but for those of you using python rather than js. https://github.com/Antar1011/Smogon-Usage-Stats
 
Last edited:
I'm almost done with the usage stats API, only I have a couple of hang ups, if anyone can help me sort it out.

I'm using Python Flask (mostly to get experienced with it) to handle the get requests. It connects to my database, but returns a list of dictionaries, whereas I would prefer a dictionary of dictionaries (to be in JSON format, because I plan to use it for a webapp I'm making). I know, in theory, I could just go through and remap things and all that in my javascript code, but everyone else would as well and that's just making more work. I have posted my question on StackOverflow if anyone cares to have a look at it, but then I should be able to deploy it by the weekend if all goes according to plan and the Gods are kind.

https://stackoverflow.com/questions/64791489/flask-change-output-from-response/64791927#64791927

I guess if this is not possible to do (which it should be) then I can just rewrite it using Express or something else.
 

Users Who Are Viewing This Thread (Users: 1, Guests: 0)

Top