Difference between revisions of "Mojang API"
m (I'm able to make json post requests to https://api.mojang.com/profiles/minecraft without the User-Agent "minecraft", assuming this information to be outdated I've removed it) |
Scholzi100 (talk | contribs) m |
||
Line 188: | Line 188: | ||
** [https://github.com/mapcrafter/mapcrafter-playermarkers/blob/c583dd9157a041a3c9ec5c68244f73b8d01ac37a/playermarkers/player.php#L8-L19 PHP] | ** [https://github.com/mapcrafter/mapcrafter-playermarkers/blob/c583dd9157a041a3c9ec5c68244f73b8d01ac37a/playermarkers/player.php#L8-L19 PHP] | ||
** [https://github.com/LapisBlue/Lapitar/blob/55ede80ce4ebb5ecc2b968164afb40f61b4cc509/mc/uuid.go#L34-L36 Go] | ** [https://github.com/LapisBlue/Lapitar/blob/55ede80ce4ebb5ecc2b968164afb40f61b4cc509/mc/uuid.go#L34-L36 Go] | ||
− | ** [https://github.com/crafatar/crafatar/blob/9d2fe0c45424de3ebc8e0b10f9446e7d5c3738b2/lib/skins.js#L90-L108 | + | ** [https://github.com/crafatar/crafatar/blob/9d2fe0c45424de3ebc8e0b10f9446e7d5c3738b2/lib/skins.js#L90-L108 JavaScript] (includes explanation) |
** [https://gist.github.com/jomo/9968b8d572c38e1b1f4c#file-main-java-L4-L11 Java] (includes sample UUIDs) | ** [https://gist.github.com/jomo/9968b8d572c38e1b1f4c#file-main-java-L4-L11 Java] (includes sample UUIDs) | ||
* Likewise <code>"CAPE"</code> will be missing if the account has no cape. | * Likewise <code>"CAPE"</code> will be missing if the account has no cape. |
Revision as of 15:28, 2 December 2016
Contents
Notes
- All public APIs are rate limited so you are expected to cache the results. This is currently set at 600 requests per 10 minutes but this may change.
- For some parts of the API, demo accounts are sometimes included, sometimes not. Mojang keeps changing this.
API Status
GET https://status.mojang.com/check
Returns status of various Mojang services. Possible values are green
(no issues), yellow
(some issues), red
(service unavailable).
Response
[
{
"minecraft.net": "yellow"
},
{
"session.minecraft.net": "green"
},
{
"account.mojang.com": "green"
},
{
"auth.mojang.com": "green"
},
{
"skins.minecraft.net": "green"
},
{
"authserver.mojang.com": "green"
},
{
"sessionserver.mojang.com": "yellow"
},
{
"api.mojang.com": "green"
},
{
"textures.minecraft.net": "red"
},
{
"mojang.com": "green"
}
]
Username -> UUID at time
GET https://api.mojang.com/users/profiles/minecraft/<username>?at=<timestamp>
This will return the uuid of the name at the timestamp provided.
?at=0
can be used to get the UUID of the original user of that username, however it only works if the name was changed at least once, or if the account is legacy.
- The timestamp is a UNIX timestamp (without milliseconds)
- When the
at
parameter is not sent, the current time is used
Response
{
"id": "7125ba8b1c864508b92bb5c042ccfe2b",
"name": "KrisJelbring"
}
name
is the current name of that uuid, it is not the name requested!legacy
only appears when true (not migrated to mojang account)demo
only appears when true (account unpaid)
If there is no player with the given username an HTTP status code 204 (No Content) is sent without any HTTP body.
If the timestamp is not a number, too big or too small the HTTP status code 400 (Bad Request) is sent with an error message looking like this:
{
"error": "IllegalArgumentException",
"errorMessage": "Invalid timestamp."
}
UUID -> Name history
https://api.mojang.com/user/profiles/<uuid>/names
Returns all the usernames this user has used in the past and the one they are using currently. The UUID must be given without hyphens.
Response
[
{
"name": "Gold"
},
{
"name": "Diamond",
"changedToAt": 1414059749000
}
]
The changedToAt
field is a Java timestamp in milliseconds.
Playernames -> UUIDs
POST https://api.mojang.com/profiles/minecraft
This will return player UUIDS and some extras.
Payload
[
"maksimkurb",
"nonExistingPlayer" //Test for non-existing player
]
Response
[
{
"id": "0d252b7218b648bfb86c2ae476954d32",
"name": "maksimkurb",
"legacy": true,
"demo": true
}
]
- name is case-corrected
- legacy only appears when true (profile not migrated to mojang.com)
- demo only appears when true (account unpaid)
- IllegalArgumentException is returned when any of the usernames is null or ""
- The
Content-Type
HTTP header must beapplication/json
- You cannot request more than 100 names per request
UUID -> Profile + Skin/Cape
https://sessionserver.mojang.com/session/minecraft/profile/<uuid>
This will return the player's username plus any additional information about them (e.g. skins). Example: https://sessionserver.mojang.com/session/minecraft/profile/4566e69fc90748ee8d71d7ba5aa00d20
This has a much stricter rate limit: You can request the same profile once per minute, however you can send as many unique requests as you like.
Response
{
"id": "<profile identifier>",
"name": "<player name>",
"properties": [
{
"name": "textures",
"value": "<base64 string>",
"signature": "<base64 string; signed data using Yggdrasil's private key>" // Only provided if ?unsigned=false is appended to url
}
]
}
The "value" base64 string for the "textures" object decoded:
{
"timestamp": "<java time in ms>",
"profileId": "<profile uuid>",
"profileName": "<player name>",
"isPublic": "<true or false>",
"textures": {
"SKIN": {
"url": "<player skin URL>"
},
"CAPE": {
"url": "<player cape URL>"
}
}
}
- The timestamp is sometimes in the past (probably due to cached results?)
- The
"SKIN"
object will have"metadata": {"model": "slim"}
if the player model has slim arms (“Alex?” style). For square arms (“Steve?” style),"metadata"
will be missing. - If no custom skin has been set,
"SKIN"
will be missing.
Whether the player has the “Alex?” or “Steve?” skin depends on the Java hashCode of their UUID. Steve is used for even hashes. Example implementations:- PHP
- Go
- JavaScript (includes explanation)
- Java (includes sample UUIDs)
- Likewise
"CAPE"
will be missing if the account has no cape.
Change Skin
POST https://api.mojang.com/user/profile/<uuid>/skin
This will set the skin for the selected profile, but Mojang's servers will fetch the skin from a URL. This will also work for legacy accounts.
Response
Upon error the server will send back a JSON with the error. (Success is a blank payload)
Headers
Authorization: Bearer <access token>
Payload
The payload for this API consists of two url-encoded form fields (conjoined by '&').
model=<""/"slim">&url=<skin url>
model is an empty string for the default model and "slim" for the slim model
Example
curl -H "Authorization: Bearer <access token>" --data-urlencode "model=" --data-urlencode "url=http://assets.mojang.com/SkinTemplates/steve.png" https://api.mojang.com/user/profile/<uuid>/skin
POST /user/profile/<uuid>/skin HTTP/1.1 Host: api.mojang.com User-Agent: curl/7.49.0 Accept: */* Authorization: Bearer <access token> Content-Length: 69 Content-Type: application/x-www-form-urlencoded model=&url=http%3A%2F%2Fassets.mojang.com%2FSkinTemplates%2Fsteve.png
Upload Skin
PUT https://api.mojang.com/user/profile/<uuid>/skin
This uploads a skin to Mojang's servers. It also sets the users skin. This works on legacy counts as well.
Response
No response unless error
Headers
Authorization: Bearer <access token>
Payload
The payload for this API consists of multipart form data. There are two parts (order does not matter b/c of boundary):
model | Empty string for the default model and "slim" for the slim model |
file | Raw image file data |
Example
curl -X PUT -H "Authorization: Bearer <access token>" -F model=alex -F file="@alex.png;type=image/png" https://api.mojang.com/user/profile/<uuid>/skin
PUT /user/profile/<uuid>/skin HTTP/1.1 Host: api.mojang.com User-Agent: curl/7.49.0 Accept: */* Authorization: Bearer <access token> Content-Length: <length> Content-Type: multipart/form-data; boundary=<boundary> --<boundary> Content-Disposition: form-data; name="model" slim --<boundary> Content-Disposition: form-data; name="file"; filename="alex.png" Content-Type: image/png <image data> --<boundary>--
Reset Skin
DELETE https://api.mojang.com/user/profile/<uuid>/skin
Resets the users skin to the default one.
Response
No response unless error
Headers
Authorization: Bearer <access token>
Example
curl -X DELETE -H "Authorization: Bearer <access token>" https://api.mojang.com/user/profile/<uuid>/skin
DELETE /user/profile/<uuid>/skin HTTP/1.1 Host: api.mojang.com User-Agent: curl/7.46.0 Accept: */* Authorization: Bearer <access token>
User Info
GET https://api.mojang.com/user
Returns information on the logged in Mojang account.
Response
{
"id": "<Account Identifier?>",
"email": "<Email attached to account>",
"username": "<Username of account, with migrated accounts this is the same as email>",
"registerIp": "<IP used to register account>",
"registeredAt": <Epoch timestamp in ms of date the Mojang account was registered>,
"passwordChangedAt": <Epoch timestamp of time password was last changed>,
"dateOfBirth": <Epoch timestamp of date of birth for this Mojang Account>,
"deleted": <Unknown, probably whether account has been deleted or not>,
"blocked": <Unknown, probably whether account has been blocked or not>,
"secured": <Whether security questions are enabled on this Mojang Account>,
"migrated": <Whether the account has been migrated, if the account was made after Mojang Accounts were mandatory for new accounts this is set to false>,
"emailVerified": <Whether the email attached to the account is verified>,
"legacyUser": <Whether the account is a legacy user?>,
"verifiedByParent": <Whether the account has been verified by parent, is set to false if no parent verification was needed>,
"fullName": "<Full name attached to Mojang account, can be an empty string>",
"fromMigratedUser": <Not sure, probably related to migrated?>,
"hashed": <Unsure, seems to be set to false?>
}
Headers
Authorization: Bearer <access token>
Blocked Servers
GET https://sessionserver.mojang.com/blockedservers
Returns a list of SHA1 hashes used to check server addresses against when the client tries to connect.
Clients check the lowercase name, using the ISO-8859-1 charset, against this list. They will also attempt to check subdomains, replacing each level with a *
. Specifically, it splits based off of the .
in the domain, goes through each section removing one at a time. For instance, for mc.example.com
, it would try mc.example.com
, *.example.com
, and *.com
. With IP addresses (verified by having 4 split sections, with each section being a valid integer between 0 and 255, inclusive) substitution starts from the end, so for 192.168.0.1
, it would try 192.168.0.1
, 192.168.0.*
, 192.168.*
, and 192.*
.
This check is done by the bootstrap class in netty. The default netty class is overridden by one in the com.mojang:netty dependency loaded by the launcher. This allows it to affect any version that used netty (1.7+)
Response
27ae74becc8cd701b19f25d347faa71084f69acd 986204c70d368d50ffead9031e86f2b9e70bb6d0 d42339c120bc10a393a0b1d2c6a2e0ed4dbdd61b 8bf58811e6ebca16a01b842ff0c012db1171d7d6 8789800277882d1989d384e7941b6ad3dadab430 e40c3456fb05687b8eeb17213a47b263d566f179 278b24ffff7f9f46cf71212a4c0948d07fb3bc35 7dca807cc9484b1eed109c003831faf189b6c8bf c6a2203285fb0a475c1cd6ff72527209cc0ccc6e 9f0f30820cebb01f6c81f0fdafefa0142660d688 b21d77260ed7a792c216b18c7287d683b2a271bd cc90e7b39112a48064f430d3a08bbd78a226d670 88f155cf583c930ffed0e3e69ebc3a186ea8cbb7 7ea72de5f8e70a2ac45f1aa17d43f0ca3cddeedd 605e6296b8dba9f0e4b8e43269fe5d053b5f4f1b 4a1b3b860ba0b441fa722bbcba97a614f6af9bb8 e2e12f3b7b85eab81c0ee5d2e9e188df583fe281 b8c876f599dcf5162911bba2d543ccbd23d18ae5 48f04e89d20b15de115503f22fedfe2cb2d1ab12 9a9ae8e9d0b6f3bf54c266dcd1e4ec034e13f714 336e718ffbc705e76b4a72884172c6b95216b57c 27cf97ecf24c92f1fe5c84c5ff654728c3ee37dd 0acba7b130712cb4260d40b031fe36c668cdefce 32066aa0c7dc9b097eed5b00c5629ad03f250a2d 5d2e23d164a43fbfc4e6093074567f39b504ab51 79aecb5b9fafced11f05bbb6939262f5d4e3626b f3df314d1f816a8c2185cd7d4bcd73bbcffc4ed8 65ca8860fa8141da805106c0389de9d7c17e39bf dcc1f876e258ac5ecab28244da7a94ed44d4b43f 6f2520f8bd70a718c568ab5274c56bdbbfc14ef4 b13009db1e2fbe05465716f67c8d58b9c0503520 3e560742576af9413fca72e70f75d7ddc9416020 e3985eb936d66c9b07aa72c15358f92965b1194e b140bec2347bfbe6dcae44aa876b9ba5fe66505b c005ad34245a8f2105658da2d6d6e8545ef0f0de 11a2c115510bfa6cb56bbd18a7259a4420498fd5 75df09492c6c979e2db41116100093bb791b8433 c78697e385bfa58d6bd2a013f543cdfbdc297c4f c645d6c6430db3069abd291ec13afebdb320714b 709a849e4e7a986c8165083dccb9857bcb04c67b 073ca448ef3d311218d7bd32d6307243ce22e7d0 33839f4006d6044a3a6675c593fada6a690bb64d
Some of the current hashes have been cracked.
6f2520f8bd70a718c568ab5274c56bdbbfc14ef4:*.minetime.com 7ea72de5f8e70a2ac45f1aa17d43f0ca3cddeedd:*.trollingbrandon.club c005ad34245a8f2105658da2d6d6e8545ef0f0de:*.skygod.us c645d6c6430db3069abd291ec13afebdb320714b:*.mineaqua.es 8bf58811e6ebca16a01b842ff0c012db1171d7d6:*.eulablows.host 8789800277882d1989d384e7941b6ad3dadab430:*.moredotsmoredots.xyz e40c3456fb05687b8eeb17213a47b263d566f179:*.brandonlovescock.bid 278b24ffff7f9f46cf71212a4c0948d07fb3bc35:*.brandonlovescock.club c78697e385bfa58d6bd2a013f543cdfbdc297c4f:*.mineaqua.net b13009db1e2fbe05465716f67c8d58b9c0503520:*.endercraft.com 3e560742576af9413fca72e70f75d7ddc9416020:*.insanefactions.org 986204c70d368d50ffead9031e86f2b9e70bb6d0:*.playmc.mx 65ca8860fa8141da805106c0389de9d7c17e39bf:*.howdoiblacklistsrv.host dcc1f876e258ac5ecab28244da7a94ed44d4b43f:198.27.77.72 7dca807cc9484b1eed109c003831faf189b6c8bf:*.brandonlovescock.online c6a2203285fb0a475c1cd6ff72527209cc0ccc6e:*.brandonlovescock.press e3985eb936d66c9b07aa72c15358f92965b1194e:*.insanenetwork.org b140bec2347bfbe6dcae44aa876b9ba5fe66505b:*.phoenixnexus.net 27ae74becc8cd701b19f25d347faa71084f69acd:*.arkhamnetwork.org 48f04e89d20b15de115503f22fedfe2cb2d1ab12:brandonisan.unusualperson.com 9f0f30820cebb01f6c81f0fdafefa0142660d688:*.kidslovemy500dollarranks.club cc90e7b39112a48064f430d3a08bbd78a226d670:*.eccgamers.com 88f155cf583c930ffed0e3e69ebc3a186ea8cbb7:*.fucktheeula.com 605e6296b8dba9f0e4b8e43269fe5d053b5f4f1b:*.mojangendorsesbrazzers.webcam 5d2e23d164a43fbfc4e6093074567f39b504ab51:touchmybody.redirectme.net f3df314d1f816a8c2185cd7d4bcd73bbcffc4ed8:*.mojangsentamonkeyinto.space 073ca448ef3d311218d7bd32d6307243ce22e7d0:*.diacraft.org 33839f4006d6044a3a6675c593fada6a690bb64d:*.diacraft.de e2e12f3b7b85eab81c0ee5d2e9e188df583fe281:*.eulablacklist.club 11a2c115510bfa6cb56bbd18a7259a4420498fd5:*.slaughterhousepvp.com 75df09492c6c979e2db41116100093bb791b8433:*.timelesspvp.net d42339c120bc10a393a0b1d2c6a2e0ed4dbdd61b:*.herowars.org 4a1b3b860ba0b441fa722bbcba97a614f6af9bb8:justgiveinandblockddnsbitches.ddns.net b8c876f599dcf5162911bba2d543ccbd23d18ae5:brandonisagainst.health-carereform.com 9a9ae8e9d0b6f3bf54c266dcd1e4ec034e13f714:brandonwatchesporn.onthewifi.com 336e718ffbc705e76b4a72884172c6b95216b57c:canyouwildcardipsplease.gotdns.ch 27cf97ecf24c92f1fe5c84c5ff654728c3ee37dd:letsplaysome.servecounterstrike.com 32066aa0c7dc9b097eed5b00c5629ad03f250a2d:mojangbrokeintomy.homesecuritymac.com
Statistics
POST https://api.mojang.com/orders/statistics
Get statistics on the sales of Minecraft.
Payload
The payload is a json list of options under the metricKeys key. Below is the default list used by https://minecraft.net/en/stats/
{
"metricKeys": [
"item_sold_minecraft",
"prepaid_card_redeemed_minecraft"
]
}
Valid options (Sales > 0) are:
item_sold_minecraft prepaid_card_redeemed_minecraft item_sold_cobalt item_sold_scrolls
Response
A json object is returned with the total amount of copies sold, the amount of copies sold in the last 24h and how many sales there are per second.
{
"total": integer total amount sold,
"last24h": integer total sold in last 24 hours,
"saleVelocityPerSeconds": integer average sales per second
}
Examples
Go | uuids or names to profiles with skins, capes and name histories
Python | uuids or names to profiles
Python | names file to uuids+names file
PHP | uuids or names to profiles with skins, heads and name histories
PHP | uuids to names
PHP | uuids to names, names to uuids
JavaScript | uuids or names to profiles with skins, capes and name histories