diff options
| author | Brian Corrigan <bcorrigan78@gmail.com> | 2017-10-04 08:48:13 -0400 |
|---|---|---|
| committer | Brian Corrigan <bcorrigan78@gmail.com> | 2017-10-04 08:48:13 -0400 |
| commit | 1542bd5e0533c535a5b4410ff83f1db8956a5acd (patch) | |
| tree | 0921b175dc5aef422e667125cefe5cf748c788e1 /en | |
| download | vainglory-docs-1542bd5e0533c535a5b4410ff83f1db8956a5acd.tar.gz vainglory-docs-1542bd5e0533c535a5b4410ff83f1db8956a5acd.zip | |
Initial commit
Diffstat (limited to 'en')
| -rw-r--r-- | en/SUMMARY.md | 17 | ||||
| -rw-r--r-- | en/assets/cover.png | 3 | ||||
| -rw-r--r-- | en/authorization.md | 98 | ||||
| -rw-r--r-- | en/book.json | 7 | ||||
| -rw-r--r-- | en/datacenters.md | 7 | ||||
| -rw-r--r-- | en/errors.md | 27 | ||||
| -rw-r--r-- | en/faq.md | 77 | ||||
| -rw-r--r-- | en/introduction.md | 27 | ||||
| -rw-r--r-- | en/links.md | 54 | ||||
| -rw-r--r-- | en/matches.md | 282 | ||||
| -rw-r--r-- | en/matchesJSON.md | 125 | ||||
| -rw-r--r-- | en/plans.md | 22 | ||||
| -rw-r--r-- | en/players.md | 195 | ||||
| -rw-r--r-- | en/requests.md | 245 | ||||
| -rw-r--r-- | en/responses.md | 73 | ||||
| -rw-r--r-- | en/samples.md | 110 | ||||
| -rw-r--r-- | en/sdks.md | 31 | ||||
| -rw-r--r-- | en/teams.md | 67 | ||||
| -rw-r--r-- | en/telemetry.md | 559 | ||||
| -rw-r--r-- | en/titles.md | 8 | ||||
| -rw-r--r-- | en/versioning.md | 9 |
21 files changed, 2043 insertions, 0 deletions
diff --git a/en/SUMMARY.md b/en/SUMMARY.md new file mode 100644 index 0000000..661b8ae --- /dev/null +++ b/en/SUMMARY.md @@ -0,0 +1,17 @@ +# Summary + +* [Versioning](versioning.md) +* [Datacenters](datacenters.md) +* [Authorization](authorization.md) +* [Titles](titles.md) +* [Making Requests](requests.md) +* [Receiving Responses](responses.md) +* [Matches](matches.md) +* [Match Data Summary](matchesJSON.md) +* [Players](players.md) +<!-- * [Samples](samples.md) --> +* [Telemetry](telemetry.md) +<!-- * [Teams \(Coming Soon\)](teams.md) --> +<!-- * [Links \(Coming Soon\)](links.md) --> +* [Community SDK's](sdks.md) +* [Errors](errors.md) diff --git a/en/assets/cover.png b/en/assets/cover.png new file mode 100644 index 0000000..d6c3ba8 --- /dev/null +++ b/en/assets/cover.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6979509c0f540cbedfb2c2941b2572a1412c50e58e47f3416726e8b8e33d7a26 +size 17187 diff --git a/en/authorization.md b/en/authorization.md new file mode 100644 index 0000000..1838477 --- /dev/null +++ b/en/authorization.md @@ -0,0 +1,98 @@ +{% method %} +# Authorization + +We require a JSON Web Token ([JWT](https://jwt.io/)) be sent along with your request via the `Authorization` header. +JWTs are passed as bearer tokens in the Authorization header, and look like the following: + +`Authorization: <Enter your API Key>` + + +There's no need to create JWTs manually, they will be created for you when you register for the API - [Register Here!](https://developer.vainglorygame.com/users/sign_in) + +In some cases an `X-API-KEY` will give you more access to information, and in all cases it means that you are operating under a per-token rate limit. + +{% sample lang="shell" %} +> To specify the Headers, use this code: + +```shell + # With shell, you can just pass the correct header with each request + curl "<endpoint-url>" \ + -H "Authorization: <api-key>" + -H "Accept: application/vnd.api+json" +``` +{% sample lang="java" %} +```java +import java.io.*; +import java.net.*; + +URL url = new URL("<endpoint-url>"); +HttpURLConnection conn = (HttpURLConnection) url.openConnection(); +conn.setRequestMethod("GET"); +conn.setRequestProperty("Authorization","<api-key>"); +conn.setRequestProperty("Accept", "application/vnd.api+json"); + +conn.getInputStream() +``` + +{% sample lang="python" %} +```python +import requests + +url = "<endpoint-url>" + +header = { + "Authorization": "<api-key>", + "Accept": "application/vnd.api+json" +} + +r = requests.get(url, headers=header) +``` +{% sample lang="ruby" %} +```ruby +``` +{% sample lang="js" %} +```javascript +``` + +{% sample lang="go" %} +```go +import "net/http" + +client := &http.Client{} +req, _ := http.NewRequest("GET","<endpoint-url>",nil) +req.Header.Set("Authorization", "<api-key>") +req.Header.Set("Accept", "application/vnd.api+json") +res, _ := client.Do(req) +``` + +{% sample lang="swift" %} +```swift +import Foundation + +let urlString = endpoint-url" + +let url = NSURL(string: urlString) +var downloadTask = URLRequest(url: (url as URL?)!, cachePolicy: URLRequest.CachePolicy.ReloadIgnoringCacheData, timeoutInterval: 20) + +downloadTask.httpMethod = "GET" + +downloadTask.addValue("apiKey", forHTTPHeaderField: "Authorization") +downloadTask.addValue("application/vnd.api+json", forHTTPHeaderField: "Accept") + +URLSession.shared.dataTask(with: downloadTask) { (data, response, error) in +if let response = response { + print(response) +} + +if let data = data { + do { + let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary + print(jsonData!.value(forKey: "data") as Any) + } catch { + print(error) + } +} +}.resume() +``` + +{% endmethod %} diff --git a/en/book.json b/en/book.json new file mode 100644 index 0000000..20b0b88 --- /dev/null +++ b/en/book.json @@ -0,0 +1,7 @@ +{ + "language": "en", + "structure": { + "readme": "introduction.md", + "summary": "summary.md" + } +} diff --git a/en/datacenters.md b/en/datacenters.md new file mode 100644 index 0000000..1a3b311 --- /dev/null +++ b/en/datacenters.md @@ -0,0 +1,7 @@ +# Datacenters + +We operate several Datacenters around the world. Each datacenter holds all +information for one or more Regions of the game. Currently all data is located +in `DC01`, but this may change in the future. Users will be notified prior to the +change and an API endpoint will be made available to provide metadata describing +where each regions data can be found.
\ No newline at end of file diff --git a/en/errors.md b/en/errors.md new file mode 100644 index 0000000..a23e0dd --- /dev/null +++ b/en/errors.md @@ -0,0 +1,27 @@ +# Errors + +The server will stop processing if a problem is encountered and return the correct +HTTP error status code. Errors may additionally include error objects, which are +returned as an array keyed by `errors` in the top level of a JSON API document. + +An error objects have the following members: + +* `title`: (Required) the HTTP status code applicable to this problem, expressed as a + string value. +* `description`: (Optional) a short summary of the problem + +The Server uses the following error codes: + +Error Code | Meaning +---------- | ------- +400 | Bad Request -- Your request sucks +401 | Unauthorized -- Your API key is wrong +403 | Forbidden -- The object requested is hidden for administrators only +404 | Not Found -- The specified object could not be found +405 | Method Not Allowed -- You tried to access a object with an invalid method +406 | Not Acceptable -- You requested a format that isn't JSON +410 | Gone -- The object requested has been removed from our servers +418 | I'm a teapot +429 | Too Many Requests -- You're requesting too much data! Slow down! +500 | Internal Server Error -- We had a problem with our server. Try again later. +503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. diff --git a/en/faq.md b/en/faq.md new file mode 100644 index 0000000..39d6bf4 --- /dev/null +++ b/en/faq.md @@ -0,0 +1,77 @@ +### GETTING STARTED: +<br> +######Q: Where can I sign up for an API key? +A: On the [Vainglory API Developer Portal](https://developer.vainglorygame.com) + +######Q: I have my API Key. What do I do now? +A: To get started, take a look at the [Documentation](https://developer.vainglorygame.com/docs) where you can learn how to use the API. + +######Q: Where is the documentation? +A: Documentation is [right here.](https://developer.vainglorygame.com/docs) + +######Q: How far along in development is the API? +A: The API is currently in Alpha. Alpha software can be unstable and could cause crashes or data loss. Alpha software may not contain all of the features that are planned for the final version. + +######Q: I’ve never coded anything before and I have a sweet idea, how do I get started? +A: Head over to our public [Discord](https://discord.me/vaingloryapi) and chat with some of the developers and designers who are already building tools with the API. Many of them would be happy to help you get started on your project! + +######Q: When I signed up, it said I was enrolled in the Community Free Tier, what does that mean? +A: The Community Free Tier allows you to begin developing and testing your app/tool using live data. It comes with a default rate limit of 10 requests per minute that is adequate for testing purposes. + +######Q: My dashboard says that my rate limit is 10 requests per minute. How can I request a higher rate limit? +A: The default rate limit of 10 requests per minute is for testing/development purposes only. Once you are ready to launch your tool, you can request a higher rate limit by emailing api@superevilmegacorp.com + +######Q: What can I do with the data I get from the API? +A: Build awesome tools for yourself, or for the community! You can derive any information you’d like from the data, but you cannot scrape or store all of the data from the API. For a full list of what is acceptable and what is not, check out the [Terms of Service](https://developer.vainglorygame.com/terms-of-service). + +######Q: Will you charge for use of the API? +A: The API is free for non-commercial use. For a commercial license, send an email to api@superevilmegacorp.com + +######Q: How do I know if I need a commercial license? +A: If you are doing any of the following, you will need to register for a commercial license: running ads, charging a fee to access your tool, selling aggregated data, monetizing on the data provided in any way. + +######Q: What can I do with a commercial license? +A: With the API still in Alpha, we are not distributing commercial licenses yet. We will have more information on this soon. In the meantime, you can check the Terms of Service to see what are acceptable uses for the API. + +######Q: How do I get a commercial license? +A: With the API still in Alpha, we are not distributing commercial licenses yet. If you have further questions, or want to chat about it more, send an email to api@superevilmegacorp.com + +######Q: If I have a question regarding the API, what do I do? +A: Reach out to api@superevilmegacorp.com and jump into the [Discord](https://discord.me/vaingloryapi) chat server. +<br> +### Development/Troubleshooting: +<br> +######Q: The documentation seems wrong. What do I do now? +A: With the API still in Alpha, it’s very possible the docs are not completely up-to-date. We’re updating the docs as we go! You can also contribute to the docs on [Github](https://github.com/madglory/gamelocker-vainglory) if you’d like to make some changes. + +######Q: I just played a match but my stats haven’t showed up yet, what’s the deal? +A: The API defaults to searching for matches over the last 3 hours. To find any matches before then, you must specify a Created-at time. + +######Q: Where can I find assets to use on my project? +A: We are working on a way to have assets available to you directly from Vainglory. In the meantime, the community has put together some great resources for you in [Discord](https://discord.me/vaingloryapi). You can find them in the pinned files in #vaingloryapi-chat. + +######Q: What endpoints do I have access to with the API? +A: Check out the [Docs](https://developer.vainglorygame.com/docs) +<br> +### API Challenge: +<br> +######Q: How do I enter the API Challenge? +A: The 2017 API Challenge submission period ended on March 26th. Check out the [list of submissions](https://developer.vainglorygame.com/rules#results). + +######Q: How will API Challange prizes be distributed for my team? +A: You can join the API Challenge with any team size up to four total. All prizes will be adjusted based on the number of members on your team (up to four). + +######Q: What features will be available for the API Challenge? +A: Some features available include Telemetry, Bulk Sample Data, + +######Q: Where do I sign up my team, or let you know I’m part of a team? +A: For the API Challenge, you don’t need to tell us what team you’re on. Where teams come into play is the submission portion of the challenge - when you submit your project, that’s when you’ll be asked who your team consists of! + +######Q: My team is making a mobile app. Can we submit that? +A: You sure can! When submitting a mobile app, we just need to see that it works. You can have it run on an emulator, Testflight, etc. If you have specific questions on this reach us at api@superevilmegacorp.com +<br> +### Beyond Alpha: +<br> +######Q: What are some more features we can expect with the API? +A: We are constantly looking to add new features to the API. In the future you can expect things like account linking, match reservations, and many more! If you would like to help impact what the API will look like in the future, join the conversation on our public [Discord](https://discord.me/vaingloryapi) channel! + diff --git a/en/introduction.md b/en/introduction.md new file mode 100644 index 0000000..9399d1b --- /dev/null +++ b/en/introduction.md @@ -0,0 +1,27 @@ +# Vainglory Developer API Guide + + + +The Vainglory Game Data Service makes it easy for players and developers to access to in-game data. + +Build something great! + +At the moment this Service is in **Preview** mode. You can see sample data, test the interface, and provide feedback to our development team. + +The Server now makes every attempt to implement the [JSON-API](http://jsonapi.org/) specification. Where a deviation occurs, it is likely unintentional and can be reported to the team in our [Discord](https://discord.me/vaingloryapi). + +We show example language bindings using CURL and plan to add libraries for Ruby, NodeJS, Java, Python and more. Community contributions are welcome and rewarded with good karma \(and swag!\) You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right. + +*** + +Download a .pdf, .epub, or .mobi file from: + +https://www.gitbook.com/book/gamelocker/vainglory/details + +Contribute content, suggestions, and fixes via either: + * [https://www.gitbook.com/book/gamelocker/vainglory](https://www.gitbook.com/book/gamelocker/vainglory) + * [https://github.com/gamelocker/vainglory](https://github.com/gamelocker/vainglory) + +*** + +<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License</a> diff --git a/en/links.md b/en/links.md new file mode 100644 index 0000000..2e600de --- /dev/null +++ b/en/links.md @@ -0,0 +1,54 @@ +# Links (Coming Soon!) + +## Get a Link + +```shell +curl "https://api.dc01.gamelockerapp.com/shards/na/link/{id}" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` + +This endpoint checks to see if a link object exists for a given code. + +### HTTP Request + +`GET https://api.dc01.gamelockerapp.com/link` + +### Query Parameters + +Parameter | Default | Description +--------- | ------- | ----------- + +## Post a Link + +```shell +curl -XPOST "https://api.dc01.gamelockerapp.com/shards/na/link/{player_id}" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` + +This endpoint creates a PlayerLink object if the verification code matches the one provided by the game. + +### HTTP Request + +`POST https://api.dc01.gamelockerapp.com/link/{player_id}` + +### Query Parameters + +Parameter | Default | Description +--------- | ------- | ----------- +code | | The verification code + +## PlayerLink + +```json +{ + "attributes": { + "playerId": "fb374a7b-78be-4fcc-83ed-6a532a8a6f55", + "shardId": "na", + "titleId": "semc-vainglory" + }, + "id": "2454e5ac-0a69-4468-ad12-8616f066e817", + "type": "playerLink" +} +``` diff --git a/en/matches.md b/en/matches.md new file mode 100644 index 0000000..f9c43b7 --- /dev/null +++ b/en/matches.md @@ -0,0 +1,282 @@ + +# Matches + +Matches records are created every time players complete a game session. Each Match +contains high level information about the game session, including info like +duration, gameMode, and more. Each Match has two Rosters. + + +## Rosters + +```json +{ + "type": "roster", + "id": "eca49808-d510-11e6-bf26-cec0c932ce01", + "attributes": { + "stats": { + "acesEarned": 2, + "gold": 32344, + "etc..." + } + }, + "relationships": { + "team": { + "data": { + "type": "team", + "id": "753d464c-d511-11e6-bf26-cec0c932ce01" + } + }, + "participants": { + "data": [ + { + "type": "participant", + "id": "eca49a7e-d510-11e6-bf26-cec0c932ce01" + }, + "etc..." + ] + } + } +} +``` + +Rosters track the scores of each opposing group of Participants. If players entered +matchmaking as a team, the Roster will have a related Team. Rosters have many Participants +objects, one for each member of the Roster. Roster objects are only meaningful +within the context of a Match and are not exposed as a standalone resource. + +## Participants + +```json +{ + "type": "participant", + "id": "ea77c3a7-d44e-11e6-8f77-0242ac130004", + "attributes": { + "actor": "*Hero009*", + "stats": { + "assists": 4, + "crystalMineCaptures": 1, + "deaths": 2, + "farm": 49.25, + "etc..." + } + } +} +``` +Participant objects track each member in a Roster. Participants may be +anonymous Players, registered Players, or bots. In the case where the Participant +is a registered Player, the Participant will have a single Player relationship. +Participant objects are only meaningful within the context of a Match and are +not exposed as a standalone resource. + +{% method %} + +## Get a collection of Matches + +This endpoint retrieves data from matches. Bulk scraping matches is prohibited. + + +{% sample lang="shell" %} +```shell +curl -g "https://api.dc01.gamelockerapp.com/shards/na/matches?sort=createdAt&page[limit]=3&filter[createdAt-start]=2017-02-27T13:25:30Z&filter[playerNames]=<playerName>" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` + +{% sample lang="java" %} +```java +//There are a variety of Java HTTP libraries that support query-parameters. +``` + +{% sample lang="python" %} +```python +import requests +url = "https://api.dc01.gamelockerapp.com/shards/na/matches" +header = { + "Authorization": "<api-key>", + "Accept": "application/vnd.api+json" +} +query = { + "sort": "createdAt", + "filter[playerNames]": "<playerName>", + "filter[createdAt-start]": "2017-02-28T13:25:30Z", + "page[limit]": "3" +} +r = requests.get(url, headers=header, params=query) +``` + +{% sample lang="ruby" %} +```ruby + +``` + +{% sample lang="js" %} +```javascript + +``` + +{% sample lang="go" %} +```go +q := req.URL.Query() +q.Add("sort", "createdAt") +q.Add("filter[playerNames]", "<playerName>") +q.Add("filter[createdAt-start]", "2017-02-27T13:25:30Z") +q.Add("page[limit]", "3") +req.URL.RawQuery = q.Encode() +res, _ := client.Do(req) +``` + +{% common %} +> The above command returns JSON structured like this: + +```json +{ + "data": [ + { + "type": "match", + "id": "02b90214-c64d-11e6-9f6b-062445d3d668", + "attributes": { + "createdAt": "2017-01-06T20:30:08Z", + "duration": 1482195372, + "gameMode": "casual", + "patchVersion": "1.0.0", + "shardId": "na", + "stats": "acesEarned: 3, etc..." + }, + "relationships": { + "rosters": { + "data": [{ + "type": "roster", + "id": "ea77c2eb-d44e-11e6-8f77-0242ac130004" + }, { + "type": "roster", + "id": "dc2c14b4-d50c-11e6-bf26-cec0c932ce01" + }] + } + } + } + ] +} +``` +{% endmethod %} + + +### HTTP Request + +`GET https://api.dc01.gamelockerapp.com/shards/na/matches` + +### Query Parameters + +Parameter | Default | Description +--------- | ------- | ----------- +page[offset] | 0 | Allows paging over results +page[limit] | 50 | The default (and current maximum) is 50. Values less than 50 and great than 2 are supported. +sort | createdAt | By default, Matches are sorted by creation time ascending. +filter[createdAt-start] | 28 days prior | Must occur before end time. Format is iso8601 Usage: filter[createdAt-start]=2017-01-01T08:25:30Z +filter[createdAt-end] | 28 days after or current time | Queries search the last 3 hrs. Format is iso8601 i.e. filter[createdAt-end]=2017-01-01T13:25:30Z +filter[playerNames] | none | Filters by player name. Usage: filter[playerNames]=player1,player2,... +filter[playerIds] | none | Filters by player Id. Usage: filter[playerIds]=playerId,playerId,... +filter[teamNames] | none | Filters by team names. Team names are the same as the in game team tags. Usage: filter[teamNames]=TSM,team2,... +filter[gameMode] | none | filter by gameMode Usage: filter[gameMode]=casual,ranked,... + +<aside class="success"> +Remember — a happy match is an authenticated match! +</aside> + +{% method %} +## Get a single Match +This endpoint retrieves a specific match. + +{% sample lang="shell" %} +```shell +curl "https://api.dc01.gamelockerapp.com/shards/na/matches/<matchID>" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` + +{% sample lang="java" %} +```java +//There are a variety of Java HTTP libraries that support URL parameters +``` + +{% sample lang="python" %} +```python + +``` + +{% sample lang="ruby" %} +```ruby + +``` + +{% sample lang="js" %} +```javascript + +``` + +{% sample lang="go" %} +```go + +``` + +{% common %} + +> The above command returns JSON structured like this: + +```json +{ + "data": { + "type": "match", + "id": "02b90214-c64d-11e6-9f6b-062445d3d668", + "attributes": { + "createdAt": "2017-01-06T20:30:08Z", + "duration": 1482195372, + "gameMode": "casual", + "patchVersion": "1.0.0", + "shardId": "na", + "stats": "acesEarned: 3, etc..." + }, + "relationships": { + "rosters": { + "data": [{ + "type": "roster", + "id": "ea77c2eb-d44e-11e6-8f77-0242ac130004" + }, { + "type": "roster", + "id": "dc2c14b4-d50c-11e6-bf26-cec0c932ce01" + }] + } + } + } +} +``` +{% endmethod %} + + +### HTTP Request + +`GET https://api.dc01.gamelockerapp.com/shards/na/matches/<ID>` + +### URL Parameters + +Parameter | Description +--------- | ----------- +ID | The ID of the match to retrieve + +## Where is my match? + +We purposefully do not allow certain matches to be displayed. Specifically, for + a match to be valid it must meet all of the following requirements. + + 1. The game mode must be one of the following: + * ranked + * casual + * private + * private_party_draft_match + * private_party_aral_match + * private_party_blitz_match + * casual_aral + * blitz_pvp_ranked + 1. The match must NOT have ended with one of the following statuses: + * exitpractice + * notenoughplayers + 1. In order to allow our pro-players to practice, we also reject matches where there are no ranked players and the game mode is private. diff --git a/en/matchesJSON.md b/en/matchesJSON.md new file mode 100644 index 0000000..7004891 --- /dev/null +++ b/en/matchesJSON.md @@ -0,0 +1,125 @@ +# ***Match Data Summary*** + +Special thanks to Kashz for helping to create this! GitHub: iAm-Kashif + +## **Match Object** + +| Variable | Type | Description | +| :---: | :---: | :---: | +| type | str | Match | +| id | str | Match ID | +| createdAt | str (iso8601) | Time of Match Played | +| duration | int | Time of match in seconds | +| gameMode | str | Game Mode | +| patchVersion | str | Version of API | +| shardId | str | Match Shard | +| stats | map | See [Match.stats](#1) | +| assets | obj | See [Match.assets](#2) | +| rosters | obj | See [Rosters](#3) | + +### <a name="1"></a> **Match.stats** **(End of game statistics)** + +| Variable | Type | Description | +| :---: | :---: |:---: | +| endGameReason | str | "Victory" or "Defeat" | +| queue | str | Game Mode | + +### <a name="2"></a> **Match.assets** **(Telemetry Data)** + +| Variable | Type | Description | +| :---: | :---: |:---: | +| type | string | asset | +| createdAt | str (iso8601) | Time of Telemtry creation +| description | str | "" | +| filename | str | telemetry.json | +| id | str | ID of Asset | +| contentType | str | application/json | +| name | str | telemetry | +| url | str | Link to Telemetry.json file | + +## <a name="3"></a> **Rosters Object** + +| Variable | Type | Description | +| :---: | :---: | :---: | +| id | str | ID of Roster | +| type | str | Roster +| participants | obj | See [Participants](#4) | +| stats | obj | See [Rosters.stats](#5) | +| team | obj | See [Rosters.team](#6) | + +### <a name="5"></a>**Rosters.stats** +| Variable | Type | +| :---: | :---: | +| acesEarned | int | +| gold | int | +| heroKills | int | +| krakenCaptures | int | +| side | Either "right/red" or "left/blue" | +| turretKills | int | +| turretRemaining | int | + +### <a name="6"></a>**Rosters.team** +| Variable | Type | Description +| :---: | :---: | :---: | +| id | str | ID of Team or None | +| name | str | Name of Team or None | +| type | str | team | + +## <a name="4"></a>**Participants Object** + +| Variable | Type | Description | +| :---: | :---: | :---: | +| actor | str | Hero | +| id | str | Same as ID of Roster | +| player | obj |See [Participants.player](#7)| +| stats | map |See [Participants.stats](#8) | +| type | str | participants | + +### <a name="7"></a>**Participants.player** + +| Variable | Type |Description | +| :---: | :---: | :---: | +| id | str | UID of player | +| name | str | IGN of player | +| stats | map | See [Participants.player.stats](#9) | +| type | str | player | + +### <a name="8"></a>**Participants.stats** + +| Variable |Type | +| :---: | :---: | +| assists | int | +| crystalMineCaptures | int | +| deaths | int | +| farm | int | +| firstAfkTime | int: -1 for no AFK | +| goldMineCaptures | int | +| itemGrants | map of {itemsBought : int} | +| itemSells | map of {itemsSold : int} | +| itemUses | map of {itemsUsed : int} | +| items | list of final build (Len: 6) | +| jungleKills | int | +| karmaLevel | int | +| kills | int | +| krakenCaptures | int | +| level | int | +| minionKills | int | +| nonJungleMinionKills | int | +| skillTier | int | +| skinKey | str | +| turretCaptures | int | +| wentAfk | bool | +| winner | bool | + +### <a name="9"></a> **Participants.player.stats** + +| Variable | Type | +| :---: | :---: | +| level | int | +| lifetimeGold | float | +| lossStreak | int | +| played | int | +| played\_ranked | int | +| winStreak | int | +| wins | int | +| xp | int | diff --git a/en/plans.md b/en/plans.md new file mode 100644 index 0000000..1472ca6 --- /dev/null +++ b/en/plans.md @@ -0,0 +1,22 @@ +# Rate Limits + +The API is free for non-commercial use with a default rate limit of 10 requests per minute. If you need a higher limit, please contact api@superevilmegacorp.com and we'll hook you up! + +# Usage Tiers + +We do our best to give out timely and accurate data so that we can work together to create awesome experiences for our players. We classify projects into three categories. + +## Hobby Tier +When you create a new API key, you're automatically placed into this tier. This tier is intended to support non-commercial projects, SDKs, hackathons, and any projects that don't require a higher rate limit. + +The default rate limit is 10 requests per minute, and there is no access to data from the public beta environment. + +## Community Tier +This tier is intended to be used by small commercial projects projects (those that derive revenue from ads, subscriptions, and more). Access is still free, but we require that these projects share data with us about the way players use the project. We use this to make sure we deliver the best possible experience for both your project and the players that use it. This data is not shared with any other users of the API. + +Rate limits in this tier are customized to the project, and we allow select community projects access to the public beta environment. + +## Commercial Tier +This tier is intended to be used by large commercial projects projects (those that derive revenue from ads, subscriptions, and more). Commercial project need high-volume low-cost access to data. While the data provided is exactly the same as that provided to hobby and community tiers, commercial have additional options for accessing it. In addition, there is no requirement to share data about how data is used. + +Rate limits in this tier are customized to the project, and we allow select community projects access to the public beta environment. Commercial users also get bulk access, increased webhook limits, statistical samples, and more. diff --git a/en/players.md b/en/players.md new file mode 100644 index 0000000..0c0b92f --- /dev/null +++ b/en/players.md @@ -0,0 +1,195 @@ +# Players + +Player objects contain aggregated lifetime information about each Player. At this time Players are fairly sparse, but there are plans to add much richer data as it becomes available. + +{% method %} +## Get a single Player + +This endpoint retrieves a specific player. + +* If a player has changed names, it is possible that there are multiple ID's for a single player name. + +* Player renames do not trigger a change on this endpoint. A minimum of 1 match after the rename is required to view the change. + + +**Changes Coming!** - Player resources are not fully defined at this point, but are +included so that consumers can get basic info (name, etc.) This object will have +additional data added over the next few months, and may change slightly as data +moves from the `attributes.stats` object to the main `attributes` object. + + +{% sample lang="shell" %} +```shell +curl "https://api.dc01.gamelockerapp.com/shards/na/players/<ID>" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` + +{% sample lang="java" %} +```java +//There are a variety of Java HTTP libraries that support query-parameters. +``` + +{% sample lang="python" %} +```python + +``` + +{% sample lang="ruby" %} +```ruby + +``` + +{% sample lang="js" %} +```javascript + +``` + +{% sample lang="go" %} +```go + +``` + +{% sample lang="swift" %} +```swift +import Foundation + +let urlString = "https://api.dc01.gamelockerapp.com/shards/na/players?filter[playerNames]=PlayerIGN" + +let url = NSURL(string: urlString) +var downloadTask = URLRequest(url: (url as URL?)!, cachePolicy: URLRequest.CachePolicy.ReloadIgnoringCacheData, timeoutInterval: 20) + +downloadTask.httpMethod = "GET" + +downloadTask.addValue("apiKey", forHTTPHeaderField: "Authorization") +downloadTask.addValue("application/vnd.api+json", forHTTPHeaderField: "Accept") + +URLSession.shared.dataTask(with: downloadTask) { (data, response, error) in +if let response = response { + print(response) +} + +if let data = data { + do { + let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary + print(jsonData!.value(forKey: "data") as Any) + } catch { + print(error) + } +} +}.resume() + +``` + +{% common %} +> The above command returns JSON structured like this: + +```json +{ +"data": { + "attributes": { + "stats": { + "lossStreak": 1, + "winStreak": 0, + "lifetimeGold": 10536.0 + }, + "name": "boombastic04" + }, + "type": "player", + "id": "6abb30de-7cb8-11e4-8bd3-06eb725f8a76" +} +} +``` +{% endmethod %} + +### HTTP Request + +`GET https://api.dc01.gamelockerapp.com/shards/na/players/<ID>` + + +### URL Parameters + +Parameter | Description +--------- | ----------- +ID | The ID of the player to retrieve + +{% method %} +## Get a collection of players + +This endpoint retrieves a collection of up to 6 players, filtered by name. Player names are specific to each region. + +{% sample lang="shell" %} +```shell +curl "https://api.dc01.gamelockerapp.com/shards/na/players?filter[playerNames]=player1,player2" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` + +{% sample lang="java" %} +```java +//There are a variety of Java HTTP libraries that support query-parameters. +``` + +{% sample lang="python" %} +```python + +``` + +{% sample lang="ruby" %} +```ruby + +``` + +{% sample lang="js" %} +```javascript + +``` + +{% sample lang="go" %} +```go + +``` + +{% sample lang="swift" %} +```swift +import Foundation + +let urlString = "https://api.dc01.gamelockerapp.com/shards/na/players?filter[playerNames]=PlayerIGN1, PlayerIGN2, PlayerIGN3" + +let url = NSURL(string: urlString) +var downloadTask = URLRequest(url: (url as URL?)!, cachePolicy: URLRequest.CachePolicy.ReloadIgnoringCacheData, timeoutInterval: 20) + +downloadTask.httpMethod = "GET" + +downloadTask.addValue("apiKey", forHTTPHeaderField: "Authorization") +downloadTask.addValue("application/vnd.api+json", forHTTPHeaderField: "Accept") + +URLSession.shared.dataTask(with: downloadTask) { (data, response, error) in +if let response = response { + print(response) +} + +if let data = data { + do { + let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary + print(jsonData!.value(forKey: "data") as Any) + } catch { + print(error) + } +} +}.resume() + +``` + +{% endmethod %} + +### HTTP Request + +`GET https://api.dc01.gamelockerapp.com/shards/na/players` + +### Query Parameters + + +Parameter | Default | Description +--------- | ------- | ----------- +filter[playerNames] | none | Filters by player names. Usage: filter[playerNames]=player1,player2 diff --git a/en/requests.md b/en/requests.md new file mode 100644 index 0000000..ea2ff8a --- /dev/null +++ b/en/requests.md @@ -0,0 +1,245 @@ +# Making Requests + +## Content Negotiation + +Clients using the api should specify that they accept responses using the +`application/vnd.api+json` format, for convenience we will also accept `application/json` +since it is the default for many popular client libraries. + +The Server will respond with a `Content-Type` header that mirrors the format +requested by the Client. + +{% method %} +## Shards {#shards} +{% common %} +To specify the regional shard, use this code: + +{% sample lang="shell" %} +```shell +"...gamelockerapp.com/shards/<region>/..." +``` + +{% sample lang="java" %} +```java +"...gamelockerapp.com/shards/<region>/..." +``` + +{% sample lang="python" %} +```python +"...gamelockerapp.com/shards/<region>/..." +``` + +{% sample lang="ruby" %} +```ruby +"...gamelockerapp.com/shards/<region>/..." +``` + +{% sample lang="js" %} +```javascript +"...gamelockerapp.com/shards/<region>/..." +``` + +{% sample lang="go" %} +```go +"...gamelockerapp.com/shards/<region>/..." +``` + +{% endmethod %} + +The Vainglory Game Data Service currently supports the following regions: + +***General Region Shards*** + +To find data regarding live servers, where all data is found, please use the following shards. + +* **China:** ```cn``` +* **North America:** ```na``` +* **Europe:** ```eu``` +* **South America:** ```sa``` +* **East Asia:** ```ea``` +* **Southeast Asia (SEA):** ```sg``` + +***Tournament Region Shards*** + +To find data regarding professional eSport, which take place on the private client only, please use the following shards. + +* **North America Tournaments:** ```tournament-na``` +* **Europe Tournaments:** ```tournament-eu``` +* **South America Tournaments:** ```tournament-sa``` +* **East Asia Tournaments:** ```tournament-ea``` +* **Southeast Asia Tournaments:** ```tournament-sg``` + +***Public Beta Environment*** + +For developers that have signed an agreement with SEMC to access the Public Beta Eniroment (PBE) your key has access to an +additional shard + +* **Public Beta Environment (Coming Soon):** ```pbe``` + +**Choosing a specific region is required** +{% method %} +## GZIP + +> To specify the header Accept-Encoding, use this code: +{% sample lang="shell" %} +```shell +-H "Accept-Encoding: gzip" +``` +{% sample lang="java" %} +```java +conn.setRequestProperty("Accept-Encoding","gzip"); +``` +{% sample lang="python" %} +```python +header = {"Accept-Encoding":"gzip"} +``` +{% sample lang="ruby" %} +```ruby +``` +{% sample lang="js" %} +```javascript +``` +{% sample lang="go" %} +```go +req.Header.Set("Accept-Encoding", "gzip") +``` +{% endmethod %} +Clients can specify the header `Accept-Encoding: gzip` and the server will compress responses. +Responses will be returns with `Content-Encoding: gzip`. + +Given the size of matches, this can have significant performance benefits. + + +## Pagination + + +Where applicable, the server allows requests to limit the number of results +returned via pagination. To paginate the primary data, supply pagination information +to the query portion of the request using the limit and offset parameters. +To fetch items 2 through 10 you would specify a limit of 8 and an offset of 2: + +If not specified, the server will default for matches to`limit=5` and `offset=0`, and for players/samples to `limit=50` and `offset=0` + +<aside class="warning"> +Important - Currently the server will not allow responses with over 50 primary data objects +</aside> + +## Time + +* The max search time span between createdAt-start and createdAt-end is 28 days +* If you don't specify either createdAt-start, or createdAt-end, the default is: current time - 28 days +* If you specify only createdAt-start, createdAt-end is 28 days after or current time, whichever hits first +* If you specify only createdAt-end, createdAt-start is 28 days prior +* If you specify a future time, and are within the 28 day limit, the createdAt-end will default to current time + +{% method %} +## Sorting + +>The example below will return the oldest articles first: +{% sample lang="shell" %} +```shell +".../matches?sort=createdAt" +``` +{% sample lang="java" %} +```java +".../matches?sort=createdAt" +``` +{% sample lang="python" %} +```python +".../matches?sort=createdAt" +``` +{% sample lang="ruby" %} +```ruby +".../matches?sort=createdAt" +``` +{% sample lang="js" %} +```javascript +".../matches?sort=createdAt" +``` +{% sample lang="go" %} +```go +".../matches?sort=createdAt" +``` +{% common %} +>The example below will return the newest articles first. +{% sample lang="shell" %} + +```shell +".../matches?sort=-createdAt" +``` +{% sample lang="java" %} + +```java +".../matches?sort=-createdAt" +``` +{% sample lang="python" %} + +```python +".../matches?sort=-createdAt" +``` +{% sample lang="ruby" %} +```ruby +".../matches?sort=-createdAt" +``` +{% sample lang="js" %} + +```javascript +".../matches?sort=-createdAt" +``` +{% sample lang="go" %} +```go +".../matches?sort=-createdAt" +``` +{% endmethod %} +The default sort order is always ascending. Ascending corresponds to the +standard order of numbers and letters, i.e. A to Z, 0 to 9). For dates and times, ascending means that earlier values precede later ones e.g. 1/1/2000 will sort ahead of 1/1/2001. + +All resource collections have a default sort order. In addition, some resources provide the ability to sort according to one or more criteria ("sort fields"). + +If sort fields are is prefixed with a minus, the order will be changed to descending. + +{% method %} +## JSON-P Callbacks + +{% sample lang="shell" %} + +```shell +curl -g "https://api.dc01.gamelockerapp.com/status?callback=foo" +``` +{% endmethod %} + +You can send a ?callback parameter to any GET call to have the results wrapped in a JSON function. This is typically used when browsers want to embed content in web pages by getting around cross domain issues. The response includes the same data output as the regular API, plus the relevant HTTP Header information. + + +{% method %} + +## Cross Origin Resource Sharing + +The API supports Cross Origin Resource Sharing (CORS) for AJAX requests from any origin. +You can read the CORS W3C Recommendation, or this intro from the HTML 5 Security Guide. + +Here's a sample request sent from a browser hitting http://example.com: + + +{% sample lang="shell" %} +```shell +curl -i https://api.dc01.gamelockerapp.com/status -H "Origin: http://example.com" + HTTP/1.1 200 OK + ... + Access-Control-Allow-Origin: * + Access-Control-Expose-Headers: Content-Length +``` +{% common %} +This is what the CORS preflight request looks like: + +{% sample lang="shell" %} +```shell +curl -i https://api.dc01.gamelockerapp.com/status -H "Origin: http://example.com" -X OPTIONS + HTTP/1.1 200 OK + ... + Access-Control-Allow-Headers: Origin,X-Title-Id,Authorization + Access-Control-Allow-Methods: GET,POST,OPTIONS + Access-Control-Allow-Origin: * + Access-Control-Max-Age: 86400 +``` +{% endmethod %} diff --git a/en/responses.md b/en/responses.md new file mode 100644 index 0000000..d690dd0 --- /dev/null +++ b/en/responses.md @@ -0,0 +1,73 @@ +# Receiving Responses + +## Payload + +All Server responses contain a root JSON object. + +```jsonjson +{ + "data": { + "type": "match", + "id": "skarn", + "attributes": { + // ... this matches attributes + }, + "relationships": { + // ... this matches relationships + } + } +} +``` + +```json +{ + "data": { + "type": "match", + "id": "1" + } +} +``` + +A response will contain at least one of the following top-level members: + + * `data`: the response's “primary data” + * `errors`: an array of error objects + +A response may contain any of these top-level members: + + * `links`: a links object related to the primary data. + * `included`: an array of resource objects that are related to the primary data and/or each other (“included resources”). + +If a document does not contain a top-level data key, the included member will not be present either. + +Primary data will be either: + + * a single [resource object][resource objects], a single [resource identifier object], or `null` + * an array of [resource objects], an array of [resource identifier objects][resource identifier object], or + an empty array (`[]`) + +For example, the following primary data is a single resource object: + + +The following primary data is a single [resource identifier object] that +references the same resource: + + +A logical collection of resources will always be represented as an array, even if +it only contains one item or is empty. + +## Rate Limits +>The rate limit headers are defined as follows: + +``` +X-RateLimit-Limit - Request limit per day / per minute +X-RateLimit-Remaining - The number of requests left for the time window +X-RateLimit-Reset - The remaining window before the rate limit is refilled in UTC epoch nanoseconds. +* Limit tokens are incrementally filled by 60(sec)/ rate limit. ex: 60(sec)/10(rate) gets rate token every 6 seconds up to max rate limit. +``` +Be nice. If you're sending too many requests too quickly, we'll send back a +`429` error code (server unavailable). + +<aside class="notice"> +Free for non-commercial use for up to 10 requests per minute! To increase your rate limit, please contact api@superevilmegacorp.com +</aside> diff --git a/en/samples.md b/en/samples.md new file mode 100644 index 0000000..b7062bb --- /dev/null +++ b/en/samples.md @@ -0,0 +1,110 @@ +# Samples + +The samples endpoint provides an easy way to access hourly batches of random match data to aggregate stats. + +{% method %} +## Get a collection of Samples + +This endpoint retrieves a collection of randomly selected matches. + +{% sample lang="shell" %} +```shell +curl "https://api.dc01.gamelockerapp.com/shards/na/samples" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` + +{% sample lang="java" %} +```java +//There are a variety of Java HTTP libraries that support query-parameters. +``` + +{% sample lang="python" %} +```python + +``` + +{% sample lang="ruby" %} +```ruby + +``` + +{% sample lang="js" %} +```javascript + +``` + +{% sample lang="go" %} +```go + +``` + +{% sample lang="swift" %} +```swift + let urlString = "https://api.dc01.gamelockerapp.com/shards/na/samples" + +func downloadJsonWithTask() { + let url = NSURL(string: urlString) + + var downloadTask = URLRequest(url: (url as URL?)!, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 20) + + downloadTask.httpMethod = "GET" + downloadTask.addValue("APIKey", forHTTPHeaderField: "Authorization") + downloadTask.addValue("application/vnd.api+json", forHTTPHeaderField: "Accept") + + URLSession.shared.dataTask(with: downloadTask) { (data, response, error) in + if let response = response { + print(response) + } + + if let data = data { + do { + let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary + print(jsonData!.value(forKey: "data") as Any) + } catch { + print(error) + } + } + }.resume() + } + + +``` + +{% common %} +> The above command returns JSON structured like this: + +```json +{ + "type": "sample", + "id": "sample-na-2017-02-28T07:15:30Z", + "attributes": { + "URL": "URL of Sample Matches", + "createdAt": "2017-02-28T07:15:30Z", + "shardId": "na", + "t0": "2017-02-28T07:15:30Z", + "t1": "2017-02-28T08:15:30Z", + "titleId": "semc-vainglory" + }, + "relationships": { + "assets": { + "data": [] + } + } + } +``` +{% endmethod %} + +### HTTP Request + +`GET https://api.dc01.gamelockerapp.com/shards/na/samples` + +### Query Parameters + +Parameter | Default | Description | +--------- | ------- | ----------- +page[offset] | 0 | Allows paging over results +page[limit] | 50 | The default (and current maximum) is 50. Values less than 50 and great than 2 are supported. +sort | createdAt | By default, samples are sorted by creation time ascending. +filter[createdAt-Start] | none | Must occur before time. Format is iso8601 Usage: filter[createdAt-end]=2017-01-01T08:25:30Z +filter[createdAt-End] | none | Must occur after time. Format is iso8601 Usage: filter[createdAt-end]=2017-01-01T13:25:30Z diff --git a/en/sdks.md b/en/sdks.md new file mode 100644 index 0000000..0556f7e --- /dev/null +++ b/en/sdks.md @@ -0,0 +1,31 @@ +# Community SDK's + +Community contributions are welcome and rewarded with good karma (and swag!) If you are currently working on an API, let us know on the Discord server and we will add a link! + +##Java + +A Java adaptation of the Vainglory API - [DominicGunn/flicker](http://github.com/DominicGunn/flicker) + +##Python + +Python 3 wrapper for the Gamelocker API - [schneefux/python-gamelocker](http://github.com/schneefux/python-gamelocker) + +Python 3 wrapper for the Gamelocker API - [ClarkThyLord/madglory-ezl](https://github.com/ClarkThyLord/madglory-ezl) + +##JavaScript + +A JavaScript API client - [seripap/vainglory](https://github.com/seripap/vainglory) + +##R + +A project providing R6 classes (for the R language) for accessing the API - [nathancarter/rvgapi](https://github.com/nathancarter/rvgapi) + +##Go + +A proof of concept go client for the Vainglory Developer API - [madglory/vainglory-go-client](https://github.com/madglory/vainglory-go-client) + +##Ruby + +A Ruby gem wrapper for the Vainglory Developer API - +[Ruby Gem](https://rubygems.org/gems/vainglory-api) | +[Github](https://github.com/cbortz/vainglory-api-ruby) diff --git a/en/teams.md b/en/teams.md new file mode 100644 index 0000000..994c4fb --- /dev/null +++ b/en/teams.md @@ -0,0 +1,67 @@ +# Teams (Coming Soon!) + +Team objects contain aggregated lifetime information about each Team. + +## Get a collection of Teams + +```shell +curl "https://api.dc01.gamelockerapp.com/shards/na/teams?filter[teamNames]=team1" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` + +This endpoint retrieves a collection of up to 6 teams. + +<aside class="warning"> +Important - Team resources are not yet available in the API. +</aside> + +### HTTP Request + +`GET https://api.dc01.gamelockerapp.com/teams` + +### Query Parameters + +Parameter | Default | Description +--------- | ------- | ----------- +filter[teamNames] | none | Filters by team name. Usage: filter[teamNames]=team1 +filter[teamIds] | none | Filter by team id. Usage: filter[teamIds]=12345 + +<aside class="success"> +Remember — a happy team is an authenticated team! +</aside> + +## Get a single Team + +```shell +curl "https://api.dc01.gamelockerapp.com/teams/<ID>" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` + +```python +``` + +> The above command returns JSON structured like this: + +```json +{ + "id": 2, + "name": "Max", + "breed": "unknown", + "fluffiness": 5, + "cuteness": 10 +} +``` + +This endpoint retrieves a specific team. + +### HTTP Request + +`GET https://api.dc01.gamelockerapp.com/teams/<ID>` + +### URL Parameters + +Parameter | Description +--------- | ----------- +ID | The ID of the team to retrieve diff --git a/en/telemetry.md b/en/telemetry.md new file mode 100644 index 0000000..5ec5377 --- /dev/null +++ b/en/telemetry.md @@ -0,0 +1,559 @@ +# Telemetry + +The telemetry provides us insights into the match. It gives us details of various events that happened in the match alongwith the time when they happened. Some of the events also have location which can be plotted on a Vainglory Game map. Telemetry is very useful to generate a timeline visualization of how the match went for replays, or create heatmaps of where a certain hero or ability is most useful. These are just some of the examples of where Telemetry can be used. + +> You will get telemetry data as part of the matches endpoint. + +> And a map of the Halcyon Fold [here!](https://cdn.discordapp.com/attachments/272249149473161216/284388441674874880/vainglory-map.png) + + {% method %} +## To get Telemetry data + +You start by pulling a list of matches using the matches endopoint. + +The HTTP Request to get matches is +`GET https://api.dc01.gamelockerapp.com/shards/na/matches` + +{% sample lang="shell" %} +```shell +curl "https://api.dc01.gamelockerapp.com/shards/na/matches" \ + -H "Authorization: Bearer <api-key>" \ + -H "Accept: application/vnd.api+json" +``` +{% sample lang="java" %} +```java +//There are a variety of Java HTTP libraries that support query-parameters. +``` +{% sample lang="python" %} +```python +``` +{% sample lang="ruby" %} +```ruby +``` +{% sample lang="js" %} +```javascript +``` +{% sample lang="go" %} +```go +``` +{% common %} +> The above command returns JSON structured like this: + +```json + "data": [ + { + "type": "match", + "id": "f5373c40-0aa9-11e7-bcff-0667892d829e", + "attributes": { + "createdAt": "2017-03-17T00:38:00Z", + "duration": 259, + "gameMode": "blitz_pvp_ranked", + "patchVersion": "", + "shardId": "na", + "stats": { + "endGameReason": "victory", + "queue": "blitz_pvp_ranked" + }, + "titleId": "semc-vainglory" + }, + "relationships": { + "assets": { + "data": [ + { + "type": "asset", + "id": "b900c179-0aaa-11e7-bb12-0242ac110005" + } + ] + }, + "rosters": { + "data": [ + { + "type": "roster", + "id": "b8f6640a-0aaa-11e7-bb12-0242ac110005" + }, + { + "type": "roster", + "id": "b8f65271-0aaa-11e7-bb12-0242ac110005" + } + ] + }, + "rounds": { + "data": [] + } + } + }, + ``` + + +> You need to look for Assets JSON node which points to telemetry. Check for the following in the response: + +```json + "relationships": { + "assets": { + "data": [ + { + "type": "asset", + "id": "b900c179-0aaa-11e7-bb12-0242ac110005" + } + ] + }, +``` + +> Once you have located this ID, you now have to search for the following JSON segment in the response object. The following response object will provide you a link to the Telemetry data + +```json + { + "type": "asset", + "id": "b900c179-0aaa-11e7-bb12-0242ac110005", + "attributes": { + "URL": "https://gl-prod-us-east-1.s3.amazonaws.com/assets/semc-vainglory/na/2017/03/17/00/43/b900c179-0aaa-11e7-bb12-0242ac110005-telemetry.json", + "contentType": "application/json", + "createdAt": "2017-03-17T00:43:22Z", + "description": "", + "filename": "telemetry.json", + "name": "telemetry" + } + }, +``` + +> you can download the data with following commands. Please note that you **do not** need API Key to get this data. + +{% sample lang="shell" %} +```shell +curl "https://gl-prod-us-east-1.s3.amazonaws.com/assets/semc-vainglory/na/2017/03/17/00/43/b900c179-0aaa-11e7-bb12-0242ac110005-telemetry.json" \ + -H "Accept: application/vnd.api+json" +``` +{% sample lang="java" %} +```java +//There are a variety of Java HTTP libraries that support query-parameters. +``` +{% sample lang="python" %} +```python +``` +{% sample lang="ruby" %} +```ruby +``` +{% sample lang="js" %} +```javascript +``` +{% sample lang="go" %} +```go +``` +{% common %} +> this request will return you a response as follows: + + +```json + { "time": "2017-02-18T06:37:15+0000", + "type": "DealDamage", + "payload": { + "Team": "Left", + "Actor": "*Ringo*", + "Target": "*Turret*", + "Source": "Unknown", + "Damage": 405, + "Delt": 613, + "IsHero": 1, + "TargetIsHero": 0 + } + } +``` +{% endmethod %} + +## Event Data Dictionary +Telemetry data is classified into several events of interest. Following is a list of every event type with an example. + +### General Event Info: + +#### Team +In pre-match events teams will appear as ```1``` or ```2```, and in match events teams will apper as ```Left``` or ```Right``` side. Where ```1``` is ```Left``` side and ```2``` is ```Right``` side. + +#### Position & TargetPosition +Positions for events are given in vectors holding three values. For example: + + [-17.51, 0.01, 41.63] + +Where the first value represents the x coordinate, second value represents the z coordinate, and the third value represents the y coordinate. In other words, "Horizontal, Height, Vertical". + +The following is a list of some of the most important positions on the map: + +##### MAP LANDMARK COORDINATES + +**==LEFT SIDE==** + +```Base Shop (-88.50, 0.89, 2.00) + +Crystal (-76.12, 0.00, 19.90) + +Turret 5 (-75.48, 0.00, 11.96) +Turret 4 (-68.59, 0.00, 19.97) +Turret 3 (-54.00, 0.00, 2.92) +Turret 2 (-35.78, 0.00, 1.17) +Turret 1 (-17.06, 0.00, 1.93) + +Top Healer (-40.92, 0.00, 20.25) + +Backs 1 (-43.42, 0.00, 31.11) +Backs 2 (-45, 0.00, 32.23) + +Crystal Miner (-35.19, 0.00, 36.03) + +Mid Healer (-21.95, 0.00, 24.00) + +Fronts 1 (-14.40, 0.00, 37.67) +Fronts 2 (-12.51, 0.00, 37.67) +``` + +**==RIGHT SIDE==** +``` +Base Shop (88.57, 1.80, 0.51) + +Crystal (76.12, 0.10, 19.90) + +Turret 5 (75.48, 0.00, 11.96) +Turret 4 (68.59, 0.00, 19.97) +Turret 3 (54.00, 0.00, 2.92) +Turret 2 (35.78, 0.00, 1.17) +Turret 1 (17.06, 0.00, 1.93) + +Top Healer (40.59, 0.00, 20.75) + +Backs 1 (43.49, 0.00, 31.28) +Backs 2 (45.60, 0.00, 32.40) + +Crystal Miner (35.20, -0.00, 35.87) + +Mid Healer (22.50, 0.00, 23.50) + +Fronts 1 (14.85, 0.00, 38.12) +Fronts 2 (12.89. 0.00, 36.74) +``` +**==Miscellaneous==** +``` +Gold Miner / Kraken (0.00, 0.00. 23.60) +Elder Treant / Jungle Shop (0.20, 0.00, 42,00) +Compass Center (.092, 0.01, 3.33) +Map Center (0.00, 0.00, 0.00) +``` + +### Pre-Match Events +The following events will only take place pre-match, such as in hero selection. + +#### HeroBan +Takes place when a hero has been banned, this event will only take place in draft mode. + + { + "time": "2017-06-17T18:19:52+0000", + "type": "HeroBan", + "payload": { + "Hero": "*Grumpjaw*", + "Team": "1" + } + } + +#### HeroSelect +Takes place when a hero has been selected by a player, `Handle` is the in-game name of the player. + + { + "time": "2017-06-26T04:58:29+0000", + "type": "HeroSelect", + "payload": { + "Hero": "*Blackfeather*", + "Team": "2", + "Player": "cc4069da-982b-11e4-9bf4-06eb725f8a76", + "Handle": "CrownNorth" + } + } + +#### HeroSkinSelect +Takes place when a player has selected a skin, this event will typically happen after hero select, if not at the same time, and might appear more then once if the skin is changed. A list of all hero skins is present in the [resources folder](https://github.com/madglory/gamelocker-vainglory/tree/master/resources). + + { + "time": "2017-06-26T04:58:29+0000", + "type": "HeroSkinSelect", + "payload": { + "Hero": "*Blackfeather*", + "Skin": "Blackfeather_Skin_Dynasty_T1" + } + } + +#### HeroSwap +Takes place when a player has swapped heroes with another player, this event will only take place in draft mode. Player is the player's unique id. + + { + "time": "2017-06-13T06:41:38+0000", + "type": "HeroSwap", + "payload": [ + { + "Hero": "*Glaive*", + "Team": "2", + "Player": "85d05694-2ab2-11e5-8d94-06f4ee369f53" + }, + { + "Hero": "*Catherine*", + "Team": "2", + "Player": "292e51d6-9640-11e4-a597-06eb725f8a76" + } + ] + } + +### Match Events +The following events will only take place during a match. + +#### PlayerFirstSpawn +At the start of the game when a player spawns. + + { + "time": "2017-03-17T00:38:32+0000", + "type": "PlayerFirstSpawn", + "payload": { + "Team": "Right", + "Actor": "*Alpha*" + } + } + +#### LevelUp +When a player gains a level in the game. Depending on the game mode of the match, you will find multiple events at the exact same time for each player at the beginning of the match. + + + { + "time": "2017-03-17T00:38:32+0000", + "type": "LevelUp", + "payload": { + "Team": "Right", + "Actor": "*Alpha*", + "Level": 1, + "LifetimeGold": 0 + } + } + +#### BuyItem +When a player buys an item. Pro-Tip: Position will help you determine which shop was used to buy the item. + + { + "time": "2017-06-26T04:59:47+0000", + "type": "BuyItem", + "payload": { + "Team": "Right", + "Actor": "*Blackfeather*", + "Item": "Book Of Eulogies", + "Cost": 300, + "RemainingGold:": 300, + "Position": [ + 83.22, + 1.5, + 0.72 + ] + } + } + +#### SellItem +When a player sells an item. + + { + "time": "2017-03-31T02:49:37+0000", + "type": "SellItem", + "payload": { + "Team": "Left", + "Actor": "*Lyra*", + "Item": "Flare", + "Cost": 15 + } + } + +#### LearnAbility +When a player puts upgrades an ability. Pro-Tip: There can be a time difference between when a player levels up and upgrades an ability. + + { + "time": "2017-03-17T00:38:52+0000", + "type": "LearnAbility", + "payload": { + "Team": "Right", + "Actor": "*Sayoc*", + "Ability": "HERO_ABILITY_SAYOC_C", + "Level": 1 + } + } + +#### UseAbility +This event is recorded when a player uses an ability and it will hold information about the hero who used it together with the coordinates for the map. + + { + "time": "2017-03-17T00:39:08+0000", + "type": "UseAbility", + "payload": { + "Team": "Right", + "Actor": "*Kestrel*", + "Ability": "HERO_ABILITY_KESTREL_A_NAME", + "Position": [ + 39.39, + 0.01, + 27.26 + ] + } + } + +#### UseItemAbility +This event is recorded when a player uses an activatable item or a charm/taunt. + + { + "time": "2017-03-31T03:10:17+0000", + "type": "UseItemAbility", + "payload": { + "Team": "Left", + "Actor": "*Lyra*", + "Ability": "Travel Boots", + "Position": [ + -17.51, + 0.01, + 41.63 + ], + "TargetActor": "None", + "TargetPosition": [ + -17.51, + 0.01, + 41.63 + ] + } + } + +#### EarnXP +This event is recorded when a player gains XP from any source. it could be killing a minion, miner or a hero. Pro-Tip: This event is not shown for XP trickle(XP gained per second of the match). + + { + "time": "2017-03-17T00:39:09+0000", + "type": "EarnXP", + "payload": { + "Team": "Left", + "Actor": "*Koshka*", + "Source": "*JungleMinion_TreeEnt*", + "Amount": 67, + "Shared With": 1 + } + } + +#### DealDamage +This event is recorded when any actor (player, turret, minion, etc.) deals damage to any other. + + { + "time": "2017-03-31T02:47:34+0000", + "type": "DealDamage", + "payload": { + "Team": "Left", + "Actor": "*Skaarf*", + "Target": "*Vox*", + "Source": "Unknown", + "Damage": 105, + "Delt": 80, + "IsHero": 1, + "TargetIsHero": 1 + } + } + + +#### KillActor +This event is recorded when a player kills anything in game. it could be a a minion, miner or a hero. You will generally see EarnXP and KillActor events come at the same time. + + { + "time": "2017-03-17T00:39:09+0000", + "type": "KillActor", + "payload": { + "Team": "Left", + "Actor": "*Koshka*", + "Killed": "*JungleMinion_TreeEnt*", + "KilledTeam": "Neutral", + "Gold": "80", + "IsHero": 1, + "TargetIsHero": 0, + "Position": [ + -21.95, + 0, + 24 + ] + } + } + +#### NPCkillNPC +When one non-player actor kills another, such as the Kraken or a minion killing a turret. + + { + "time": "2017-03-31T03:07:21+0000", + "type": "NPCkillNPC", + "payload": { + "Team": "Left", + "Actor": "*Kraken_Captured*", + "Killed": "*Turret*", + "KilledTeam": "Right", + "Gold": "300", + "IsHero": 0, + "TargetIsHero": 0, + "Position": [ + 54, + 0, + 2.92 + ] + } + } + +#### Executed +When a non-player kills a player, such as Kraken or a minion killing a player. + + { + "time": "2017-06-13T06:43:40+0000", + "type": "Executed", + "payload": { + "Team": "Left", + "Actor": "*JungleMinion_TreeEnt*", + "Killed": "*Samuel*", + "KilledTeam": "Left", + "Gold": "0", + "IsHero": 0, + "TargetIsHero": 1, + "Position": [ + -41.82, + 0.01, + 27.02 + ] + } + } + +#### GoldFromTowerKill +When a player earns gold from the destruction of a turret belonging to the enemy team. + + { + "time": "2017-03-31T02:57:02+0000", + "type": "GoldFromTowerKill", + "payload": { + "Team": "Left", + "Actor": "*Idris*", + "Amount": 300 + } + } + +#### GoldFromGoldMine +When a player earns gold from his or her team capturing the gold miner. + + { + "time": "2017-03-31T03:00:43+0000", + "type": "GoldFromGoldMine", + "payload": { + "Team": "Left", + "Actor": "*Idris*", + "Amount": 300 + } + } + +#### GoldFromKrakenKill +When a player earns gold from his or her team killing a Kraken released by the enemy team. + + { + "time": "2017-03-31T03:07:43+0000", + "type": "GoldFromKrakenKill", + "payload": { + "Team": "Right", + "Actor": "*Kestrel*", + "Amount": 500 + } + } + +Download a sample of telemetry data [here!](https://cdn.discordapp.com/attachments/272249149473161216/282627164053176320/telemetry_sample.tgz) diff --git a/en/titles.md b/en/titles.md new file mode 100644 index 0000000..7c1b141 --- /dev/null +++ b/en/titles.md @@ -0,0 +1,8 @@ +# Titles + +The TitleID for a request is determined by the JWT in the Authorization header automatically and may appear in responses. + +<aside class="notice"> +No no, this isn't a hint at more Super Evil game titles. The Vainglory Game Data +Service uses a platform called Gamelocker which system itself can store multiple titles. +</aside> diff --git a/en/versioning.md b/en/versioning.md new file mode 100644 index 0000000..c90a385 --- /dev/null +++ b/en/versioning.md @@ -0,0 +1,9 @@ +## Versioning {#versioning} + +We following [SEMVER](http://semver.org/) standards, using a MAJOR.MINOR.PATCH versioning scheme. This means that we will increment versioning in the following way: + +* MAJOR version when we make incompatible API changes, +* MINOR version when we add functionality in a backwards-compatible manner, +* PATCH version when we make backwards-compatible bug fixes. + +You can see the current version and deploy date by viewing the [Status](https://api.dc01.gamelockerapp.com/status) endpoint. |
