├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── NintendoAccountBlueprint.md
├── OpenSource.md
├── Splatoon 2.paw
├── Splatoon2Blueprint.md
├── SwitchBlueprint.md
└── readme.md
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at zekesnider@me.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | If you have any questions about the API or getting anything working, feel free to open an issue and I will see if I can look into it.
4 |
5 | If you have any improvements to the documentation or corrections, opening a pull request would be much appreciated. I would be especially interested in any additional research into how the initial login URL is generated.
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2017 Zeke Snider
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/NintendoAccountBlueprint.md:
--------------------------------------------------------------------------------
1 | FORMAT: 1A
2 | HOST: https://accounts.nintendo.com
3 |
4 | # Nintendo Account API Blueprint
5 |
6 | ## Session Token [/connect/1.0.0/api/session_token]
7 |
8 | ### Get session token [POST]
9 | The body of the request should be of type Form URL-Encoded.
10 | The `session_token_code` should be `session_token_code` from the login page's redirect. `session_token_code_verifier` should be `state` from the login page's redirect. `client_id` should be the client id from the URL of your login/authentication page on Nintendo's site.
11 |
12 | + Request (application/json)
13 |
14 | + Body
15 |
16 | client_id=[client id here]&session_token_code=[session token code here]&session_token_code_verifier=[verifier code here]
17 |
18 | + Response 200 (application/json)
19 |
20 | + Body
21 |
22 | {
23 | "code": "codehere",
24 | "session_token": "sessiontokenhere"
25 | }
26 |
27 | ## Service Token [/connect/1.0.0/api/token]
28 |
29 | ### Get service token [POST]
30 |
31 | `session_token` in body of request should be the `session_token` from the response of [GET /connect/1.0.0/api/session_token](#GetSessionToken). `client_id` should be retrieved from the auth page URL.
32 |
33 | + Request (application/json)
34 | + Headers
35 | Host: accounts.nintendo.com
36 | Content-Type: application/json; charset=utf-8
37 | Connection: keep-alive
38 | User-Agent: OnlineLounge/1.0.4 NASDKAPI iOS
39 | Accept: application/json
40 | Accept-Language: en-US
41 | Accept-Encoding: gzip, deflate
42 |
43 | + Body
44 |
45 | {
46 | "client_id":"[clientidhere]",
47 | "grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer-session-token",
48 | "session_token":"Nintendo Account Session Token Here"
49 | }
50 |
51 | + Response 200 (application/json)
52 |
53 | + Body
54 |
55 | {
56 | "token_type": "Bearer",
57 | "expires_in": 900,
58 | "access_token": "accesstokenhere",
59 | "id_token": "idtokenhere",
60 | "scope": [
61 | "openid",
62 | "user",
63 | "user.birthday",
64 | "user.mii",
65 | "user.screenName"
66 | ]
67 | }
68 |
69 |
70 | ## My user details [/2.0.0/users/me]
71 |
72 | ### Get my user details [GET]
73 |
74 | Note: personal information has been redacted from the response body.
75 |
76 | Bearer token is `access_token` from the response of [GET /connect/1.0.0/api/token](#GetServiceToken)
77 |
78 | + Request
79 | + Headers
80 |
81 | Host: api.accounts.nintendo.com
82 | Connection: keep-alive
83 | Accept: application/json
84 | User-Agent: OnlineLounge/1.0.4 NASDKAPI iOS
85 | Accept-Language: en-US
86 | Authorization: Bearer [Bearer token here]
87 | Accept-Encoding: gzip, deflate
88 |
89 | + Response 200 (application/json)
90 |
91 | + Body
92 | ```json
93 | {
94 | "region": null,
95 | "isChild": false,
96 | "timezone": {
97 | "name": "America/Los_Angeles",
98 | "utcOffsetSeconds": -25200,
99 | "id": "America/Los_Angeles",
100 | "utcOffset": "-07:00"
101 | },
102 | "mii": {
103 | "clientId": "clientidhere",
104 | "storeData": {
105 | "3": "storedatahere"
106 | },
107 | "id": "mii_idhere",
108 | "imageUriTemplate": "https://{imageOrigin}/1.0.0/miis{/id}/image{/etag}.{format}{?type,expression,width,bgColor,clothesColor,cameraXRotate,cameraYRotate,cameraZRotate,characterXRotate,characterYRotate,characterZRotate,lightXDirection,lightYDirection,lightZDirection,lightDirectionMode,splitDepthOffset,splitMode,instanceCount,instanceRotationMode}",
109 | "imageOrigin": "cdn-mii.accounts.nintendo.com",
110 | "etag": "etaghere",
111 | "updatedAt": 1455678671,
112 | "favoriteColor": "green",
113 | "type": "profile"
114 | },
115 | "clientFriendsOptedIn": true,
116 | "emailVerified": true,
117 | "updatedAt": 1488606410,
118 | "screenName": "censoredemailhere / censoredusernamehere",
119 | "emailOptedInUpdatedAt": 1455678552,
120 | "emailOptedIn": true,
121 | "clientFriendsOptedInUpdatedAt": 0,
122 | "nickname": "Zeke",
123 | "eachEmailOptedIn": {
124 | "survey": {
125 | "updatedAt": 1494449469,
126 | "optedIn": true
127 | },
128 | "deals": {
129 | "optedIn": true,
130 | "updatedAt": 1494449469
131 | }
132 | },
133 | "analyticsOptedInUpdatedAt": 1455678552,
134 | "country": "US",
135 | "gender": "male",
136 | "birthday": "yyyy-mm-dd",
137 | "id": "idhere",
138 | "candidateMiis": [
139 | {
140 | "updatedAt": 1455678671,
141 | "favoriteColor": "green",
142 | "type": "candidate",
143 | "clientId": "clientidhere",
144 | "storeData": {
145 | "3": "storedatahere"
146 | },
147 | "id": "idhere",
148 | "imageUriTemplate": "https://{imageOrigin}/1.0.0/miis{/id}/image{/etag}.{format}{?type,expression,width,bgColor,clothesColor,cameraXRotate,cameraYRotate,cameraZRotate,characterXRotate,characterYRotate,characterZRotate,lightXDirection,lightYDirection,lightZDirection,lightDirectionMode,splitDepthOffset,splitMode,instanceCount,instanceRotationMode}",
149 | "imageOrigin": "cdn-mii.accounts.nintendo.com",
150 | "etag": "etaghere"
151 | },
152 | {
153 | "type": "candidate",
154 | "favoriteColor": "yellowgreen",
155 | "updatedAt": 1492719363,
156 | "etag": "etaghere",
157 | "imageOrigin": "cdn-mii.accounts.nintendo.com",
158 | "imageUriTemplate": "https://{imageOrigin}/1.0.0/miis{/id}/image{/etag}.{format}{?type,expression,width,bgColor,clothesColor,cameraXRotate,cameraYRotate,cameraZRotate,characterXRotate,characterYRotate,characterZRotate,lightXDirection,lightYDirection,lightZDirection,lightDirectionMode,splitDepthOffset,splitMode,instanceCount,instanceRotationMode}",
159 | "id": "idhere",
160 | "storeData": {
161 | "3": "storedatahere"
162 | },
163 | "clientId": "clientidhere"
164 | }
165 | ],
166 | "createdAt": 1455678552,
167 | "analyticsOptedIn": true,
168 | "language": "en-US"
169 | }
170 | ```
171 |
--------------------------------------------------------------------------------
/OpenSource.md:
--------------------------------------------------------------------------------
1 | # Open Source Dependencies
2 |
3 | This is a list of all the respositories listed under the "acknowledgements" link at the bottom of the splatoon pages in the the app, and settings menu from the main page of the app. Since those pages only list the licenses, I have compiled a list with the github/npm links.
4 |
5 | Based on the open source dependencies, I think we can safely assume that the Nintendo is using Node for the back-end API, and React for the front-end web view in the Splatoon section of the app. The main app itself is built using Xamarin (C#). Opus is used as the codec for the voice chat features.
6 |
7 |
8 | ## Switch App
9 | * Echo Cancellation Program
10 | * [libSRTP](https://github.com/cisco/libsrtp) (Note: Using version commited before [Mar 26, 2017](https://github.com/cisco/libsrtp/commit/445c1c94dc3df48fb633779d1b5d0b743bf522a4))
11 | * [Opus](https://github.com/xiph/opus)
12 | * [WebRTC AudioProcessing](https://github.com/jhgorse/webrtc-audio-processing)
13 | * [Breakpad](https://chromium.googlesource.com/breakpad/breakpad/)
14 | * [Curl](https://curl.haxx.se)
15 | * [Libdisasm](http://bastard.sourceforge.net/libdisasm.html)
16 | * [gflags](https://github.com/gflags/gflags)
17 | * [Linux SysCall Support](https://chromium.googlesource.com/linux-syscall-support/)
18 | * [musl](https://www.musl-libc.org)
19 | * [CarouselView.FormsPlugin](https://github.com/alexrainman/nativescript-carousel-view)
20 | * [Lottie](https://airbnb.design/lottie/)
21 | * [Plugins for Xamarin](https://github.com/jamesmontemagno/Xamarin.Plugins)
22 | * [Hockey SDK](https://hockeyapp.net)
23 | * [Math.NET Numerics](https://numerics.mathdotnet.com)
24 | * [Json.NET](http://www.newtonsoft.com/json)
25 | * [PCLCrypto](https://github.com/AArnott/PCLCrypto)
26 | * [P/Invoke](https://github.com/AArnott/pinvoke)
27 | * [Share Plugin](https://github.com/jguertl/SharePlugin)
28 | * [Validation](https://github.com/AArnott/Validation)
29 | * [Xamarin Forms Lab](https://github.com/XLabs/Xamarin-Forms-Labs)
30 | * [Xamarin SDK](https://open.xamarin.com)
31 | * [FFImageLoading](https://github.com/luberda-molinet/FFImageLoading)
32 | * [SkiaSharp](https://github.com/mono/SkiaSharp)
33 | * [WebP.Touch](https://github.com/luberda-molinet/WebP.Touch)
34 | * [ModernHttpClient](https://github.com/paulcbetts/ModernHttpClient)
35 |
36 | ## Splatoon 2
37 | * [ASAP](https://github.com/kriskowal/asap)
38 | * [babel-polyfill](https://github.com/babel/babel)
39 | * [babel-runtime](https://github.com/babel/babel)
40 | * [chain-function](https://github.com/jquense/chain-function)
41 | * [consolidated-events](https://github.com/lencioni/consolidated-events)
42 | * [core-js](https://github.com/zloirock/core-js) (Note: Using version commited [before Feb 24, 2016](https://github.com/zloirock/core-js/commits/master/LICENSE))
43 | * [create-react-class](https://www.npmjs.com/package/create-react-class)
44 | * [deep-equal](https://github.com/substack/node-deep-equal)
45 | * [dom-helpers](https://github.com/react-bootstrap/dom-helpers)
46 | * [encoding](https://github.com/andris9/encoding)
47 | * [exenv](https://github.com/JedWatson/exenv)
48 | * [fbjs](https://github.com/facebook/fbjs/tree/master/packages/fbjs)
49 | * [history](https://github.com/ReactTraining/history)
50 | * [hoist-non-react-statics](https://github.com/mridgway/hoist-non-react-statics)
51 | * [iconv-lite](https://github.com/ashtuchkin/iconv-lite)
52 | * [immutability-helper](https://github.com/kolodny/immutability-helper)
53 | * [immutable](https://github.com/facebook/immutable-js)
54 | * [invariant](https://github.com/zertosh/invariant)
55 | * [is-stream](https://github.com/sindresorhus/is-stream)
56 | * [isarray](https://github.com/juliangruber/isarray)
57 | * [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch)
58 | * [js-tokens](https://github.com/lydell/js-tokens)
59 | * [lodash](https://github.com/lodash/lodash)
60 | * [lodash-es](https://www.npmjs.com/package/lodash-es)
61 | * [loose-envify](https://github.com/zertosh/loose-envify)
62 | * [moment](https://github.com/moment/moment)
63 | * [mustache](https://github.com/janl/mustache.js)
64 | * [node-fetch](https://github.com/bitinn/node-fetch)
65 | * [object-assign](https://github.com/sindresorhus/object-assign)
66 | * [path-to-regexp](https://github.com/pillarjs/path-to-regexp)
67 | * [promise](https://github.com/then/promise)
68 | * [prop-types](https://github.com/facebook/prop-types)
69 | * [react](https://github.com/facebook/react)
70 | * [react-dom](https://www.npmjs.com/package/react-dom)
71 | * [react-helmet](https://github.com/nfl/react-helmet)
72 | * [react-redux](https://github.com/reactjs/react-redux)
73 | * [react-router](https://github.com/ReactTraining/react-router)
74 | * [react-router-dom](https://www.npmjs.com/package/react-router-dom)
75 | * [react-router-redux](https://github.com/ReactTraining/react-router/tree/master/packages/react-router-redux)
76 | * [react-side-effect](https://github.com/gaearon/react-side-effect)
77 | * [react-transition-group](https://github.com/reactjs/react-transition-group)
78 | * [react-waypoint](https://github.com/brigade/react-waypoint)
79 | * [reduce-reducers](https://github.com/acdlite/reduce-reducers)
80 | * [redux](https://github.com/reactjs/redux)
81 | * [redux-actions](https://github.com/acdlite/redux-actions)
82 | * [redux-saga](https://github.com/redux-saga/redux-saga)
83 | * [regenerator-runtime](https://github.com/facebook/regenerator/tree/master/packages/regenerator-runtime)
84 | * [resolve-pathname](https://github.com/mjackson/resolve-pathname)
85 | * [setimmediate](https://github.com/YuzuJS/setImmediate)
86 | * [shallowequal](https://github.com/dashed/shallowequal)
87 | * [symbol-observable](https://github.com/benlesh/symbol-observable)
88 | * [ua-parser-js](https://github.com/faisalman/ua-parser-js)
89 | * [url-search-params](https://github.com/WebReflection/url-search-params)
90 | * [uuid](https://github.com/broofa/node-uuid)
91 | * [value-equal](https://github.com/mjackson/value-equal)
92 | * [warning](https://github.com/BerkeleyTrue/warning)
93 | * [whatwg-fetch](https://github.com/github/fetch)
--------------------------------------------------------------------------------
/Splatoon 2.paw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZekeSnider/NintendoSwitchRESTAPI/409b82df5bd6f478bec07fad7362266e11d4c072/Splatoon 2.paw
--------------------------------------------------------------------------------
/SwitchBlueprint.md:
--------------------------------------------------------------------------------
1 | FORMAT: 1A
2 | HOST: https://api-lp1.znc.srv.nintendo.net
3 |
4 | # Nintendo Switch API Blueprint
5 |
6 | ## Account Login [/v1/Account/Login]
7 |
8 | It is currently not possible to generate the `f` parameter for this endpoint without using the Nintendo Switch app. For more details, see `f` details below.
9 |
10 | If you wish to use this API, extract the needed response from your phone using something like [Telerik Fiddler](http://www.telerik.com/fiddler) or [mitmproxy](https://mitmproxy.org).
11 |
12 | Or, if you wish to use exclusively the [_Splatoon 2 API_](Splatoon2Blueprint.md), extract your iksm_session from a response while on the game specific integration.
13 |
14 | ### Login to Account [POST]
15 |
16 | `naIdToken` is `id_token` from the response of [GET /connect/1.0.0/api/token](#GetServiceToken).
17 | `naBirthday` should be the birthday on the account used to login in the specified format.
18 | `timestamp` is the current [unix (epoch) timestamp](https://www.epochconverter.com).
19 | `requestId` is a generated [UUID version 4](https://www.uuidgenerator.net/version4).
20 | `f` is a parameter which is generated by the switch app. It used to be able to be generated by the splatnet2statink API, but the parameter has recently changed so this is not currently possible. For now, the only way to retrieve `f` is by using mitmproxy or similar with a device running the Nintendo switch app. For more info on `f` see [splatnet2statink API](https://github.com/frozenpandaman/splatnet2statink/wiki/api-docs) and [this issue](https://github.com/frozenpandaman/splatnet2statink/issues/56).
21 |
22 | + Request
23 |
24 | + Body
25 | {
26 | "parameter": {
27 | "language": "en-US",
28 | "naBirthday": "yyyy-mm-dd",
29 | "naCountry": "US",
30 | "naIdToken": "[tokengoeshere]",
31 | "requestId": "123e4567-e89b-12d3-a456-426655440000",
32 | "timestamp": 1537249847,
33 | "f": "[fparameterhere]"
34 | }
35 | }
36 |
37 | + Response 200 (application/json)
38 |
39 | + Body
40 |
41 | {
42 | "result": {
43 | "user": {
44 | "imageUri": "[userimagehere]",
45 | "supportId": "[supportidhere]",
46 | "name": "[namehere]",
47 | "id": [useridhere]
48 | },
49 | "firebaseCredential": {
50 | "accessToken": "firebasetokenhere",
51 | "expiresIn": 3600
52 | },
53 | "webApiServerCredential": {
54 | "accessToken": "webapitokenhere",
55 | "expiresIn": 7200
56 | }
57 | },
58 | "status": 0,
59 | "correlationId": "61becf03-0ae45082"
60 | }
61 |
62 | ## Game List [/v1/Game/ListWebServices]
63 |
64 | ### Get game list [POST]
65 |
66 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
67 |
68 | + Request
69 |
70 | + Headers
71 |
72 | Host: api-lp1.znc.srv.nintendo.net
73 | Content-Type: application/json; charset=utf-8
74 | Content-Length: 0
75 | Connection: keep-alive
76 | X-ProductVersion: 1.0.4
77 | Accept: application/json
78 | User-Agent: com.nintendo.znca/1.0.4 (iOS/10.3.3)
79 | Accept-Language: en-us
80 | X-Platform: iOS
81 | Authorization: Bearer [Web API Access Token Goes here]
82 |
83 | + Response 200 (application/json)
84 |
85 | + Body
86 |
87 | {
88 | "status": 0,
89 | "correlationId": "d02af7dc-bf169f85",
90 | "result": [
91 | {
92 | "whiteList": [
93 | "app.splatoon2.nintendo.net"
94 | ],
95 | "id": 5741031244955648,
96 | "uri": "https://app.splatoon2.nintendo.net/",
97 | "name": "Splatoon 2",
98 | "imageUri": "https://cdn.znc.srv.nintendo.net/gameWebServices/splatoon2/images/usEn/banner.png"
99 | }
100 | ]
101 | }
102 |
103 | ## Game Web Service Token [/v1/Game/GetWebServiceToken]
104 |
105 | ### Get Game Web Service Token [POST]
106 |
107 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
108 |
109 | + Request (application/json)
110 | + Headers
111 | ```
112 | Host: api-lp1.znc.srv.nintendo.net
113 | Content-Type: application/json; charset=utf-8
114 | X-ProductVersion: 1.0.4
115 | Authorization: Bearer [Web API Access Token Goes here]
116 | Accept-Language: en-us
117 | Accept-Encoding: gzip, deflate
118 | Accept: application/json; charset=utf-8
119 | User-Agent: com.nintendo.znca/1.0.4 (iOS/10.3.3)
120 | Connection: keep-alive
121 | X-Platform: iOS
122 | ```
123 | + Body
124 | ```json
125 | {
126 | "parameter": {
127 | "id": [gameIDgoeshere]
128 | }
129 | }
130 | ```
131 |
132 | + Response 200 (application/json)
133 |
134 | + Body
135 |
136 | {
137 | "result": {
138 | "accessToken": "accesstokenwillbehere",
139 | "expiresIn": 7200
140 | },
141 | "status": 0,
142 | "correlationId": "d91de63c-f186fb6f"
143 | }
144 |
145 | ## Active Event ID [/v1/Event/GetActiveEventId]
146 |
147 | ### Get Active Event ID [GET]
148 |
149 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
150 |
151 | I think this is used for the current lobby events.
152 |
153 | + Response 200 (application/json)
154 |
155 | + Body
156 |
157 | {
158 | "status": 0,
159 | "result": {
160 | "eventId": 0
161 | },
162 | "correlationId": "6c63576e-3e41f536"
163 | }
164 |
165 | ## Event List [/v1/Event/List]
166 |
167 | ### Get all events [POST]
168 |
169 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
170 |
171 | Obtains all joinable lobbies.
172 |
173 | + Request
174 |
175 | + Headers
176 |
177 | ```
178 | X-ProductVersion: 1.1.0
179 | X-Platform: Android
180 | User-Agent: com.nintendo.znca/1.1.0 (Android/7.0)
181 | Accept: application/json
182 | Authorization: Bearer [Web API access token]
183 | Content-Type: application/json; charset=utf-8
184 | Content-Length: 0
185 | Host: api-lp1.znc.srv.nintendo.net
186 | Connection: Keep-Alive
187 | Accept-Encoding: gzip
188 | ```
189 |
190 | + Response 200 (application/json)
191 |
192 | + Body
193 |
194 | ```json
195 | {
196 | "correlationId": "499ab925-56d67923",
197 | "status": 0,
198 | "result": [
199 | {
200 | "allowJoinGameWithoutCoral": false,
201 | "members": [
202 | {
203 | "isPlaying": false,
204 | "isInvited": true,
205 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/ae160604808ae5ad",
206 | "id": 6403160302157824,
207 | "name": "Virepri"
208 | },
209 | {
210 | "isPlaying": true,
211 | "isInvited": true,
212 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/26f4a1e2a08ee69b",
213 | "id": 5409588421591040,
214 | "name": "TPoS-Shin"
215 | }
216 | ],
217 | "gameStatus": {
218 | "isClosed": false
219 | },
220 | "id": 5714341576835072,
221 | "passCode": "",
222 | "shareUri": "https://lounge.nintendo.com/room/DDx46PX1Ck",
223 | "ownerUserId": 5409588421591040,
224 | "game": {
225 | "instructionPageUri": "",
226 | "minMember": 1,
227 | "imageUri": "",
228 | "maxMember": 1,
229 | "selectedGameMode": {
230 | "instructionPageUri": "https://web-lp1.znc.srv.nintendo.net/games/hac-aab6b/gameModes/SalmonRun/howtoJoin/index.html",
231 | "minMember": 1,
232 | "imageUri": "https://cdn.znc.srv.nintendo.net/games/hac-aab6b/gameModes/SalmonRun/images/usEn/banner.jpg",
233 | "maxMember": 1,
234 | "id": 5,
235 | "name": "Salmon Run",
236 | "ogpTitle": "Join {room_name} now!"
237 | },
238 | "id": 5741031244955648,
239 | "voiceChatBackgroundImageUri": "https://cdn.znc.srv.nintendo.net/games/hac-aab6b/voiceChat/background.webp",
240 | "name": "Splatoon 2",
241 | "officialSiteUri": "http://www.nintendo.com/games/detail/splatoon-2-switch"
242 | },
243 | "description": "",
244 | "name": "TPoS-Shin's Room"
245 | }
246 | ]
247 | }
248 | ```
249 |
250 | ## Show Event [/v1/Event/Show]
251 |
252 | ### [POST]
253 |
254 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
255 |
256 | + Request (application/json)
257 |
258 | + Headers
259 |
260 | ```
261 | X-ProductVersion: 1.1.0
262 | X-Platform: Android
263 | User-Agent: com.nintendo.znca/1.1.0 (Android/7.0)
264 | Accept: application/json
265 | Authorization: Bearer [Web API Access Token]
266 | Content-Type: application/json; charset=utf-8
267 | Content-Length: 37
268 | Host: api-lp1.znc.srv.nintendo.net
269 | Connection: Keep-Alive
270 | Accept-Encoding: gzip
271 | ```
272 |
273 | + Body
274 |
275 | ```json
276 | {
277 | "parameter":{
278 | "id":5714341576835072
279 | }
280 | }
281 | ```
282 |
283 | + Response 200 (application/json)
284 |
285 | + Body
286 |
287 | ```json
288 | {
289 | "result": {
290 | "passCode": "",
291 | "id": 5714341576835072,
292 | "description": "",
293 | "ownerUserId": 5409588421591040,
294 | "shareUri": "https://lounge.nintendo.com/room/DDx46PX1Ck",
295 | "members": [
296 | {
297 | "id": 6403160302157824,
298 | "name": "Virepri",
299 | "isPlaying": false,
300 | "isInvited": true,
301 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/ae160604808ae5ad"
302 | },
303 | {
304 | "id": 5409588421591040,
305 | "name": "TPoS-Shin",
306 | "isPlaying": true,
307 | "isInvited": true,
308 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/26f4a1e2a08ee69b"
309 | }
310 | ],
311 | "allowJoinGameWithoutCoral": false,
312 | "name": "TPoS-Shin's Room",
313 | "game": {
314 | "officialSiteUri": "http://www.nintendo.com/games/detail/splatoon-2-switch",
315 | "id": 5741031244955648,
316 | "minMember": 1,
317 | "imageUri": "",
318 | "voiceChatBackgroundImageUri": "https://cdn.znc.srv.nintendo.net/games/hac-aab6b/voiceChat/background.webp",
319 | "instructionPageUri": "",
320 | "maxMember": 1,
321 | "selectedGameMode": {
322 | "id": 5,
323 | "minMember": 1,
324 | "imageUri": "https://cdn.znc.srv.nintendo.net/games/hac-aab6b/gameModes/SalmonRun/images/usEn/banner.jpg",
325 | "name": "Salmon Run",
326 | "ogpTitle": "Join {room_name} now!",
327 | "maxMember": 1,
328 | "instructionPageUri": "https://web-lp1.znc.srv.nintendo.net/games/hac-aab6b/gameModes/SalmonRun/howtoJoin/index.html"
329 | },
330 | "name": "Splatoon 2"
331 | },
332 | "gameStatus": {
333 | "isClosed": false
334 | }
335 | },
336 | "correlationId": "4b0d88f2-e642524a",
337 | "status": 0
338 | }
339 | ```
340 |
341 | ## Invite to Event [/v1/Event/Invite]
342 |
343 | ### Invite to Event [POST]
344 |
345 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
346 |
347 | + Request
348 |
349 | + Headers
350 |
351 | ```
352 | X-ProductVersion: 1.1.0
353 | X-Platform: Android
354 | User-Agent: com.nintendo.znca/1.1.0 (Android/7.0)
355 | Accept: application/json
356 | Authorization: Bearer [Web API Access Token]
357 | Content-Type: application/json; charset=utf-8
358 | Content-Length: 71
359 | Host: api-lp1.znc.srv.nintendo.net
360 | Connection: Keep-Alive
361 | Accept-Encoding: gzip
362 | ```
363 |
364 | + Body
365 |
366 | ```json
367 | {
368 | "parameter": {
369 | "id": 5123588421058560,
370 | "users": [
371 | {
372 | "id": 5409588421591040
373 | }
374 | ]
375 | }
376 | }
377 | ```
378 |
379 | + Response
380 |
381 | + Body
382 |
383 | ```json
384 | {
385 | "result": {},
386 | "status": 0,
387 | "correlationId": "ae0f0cf7-f03bfb4e"
388 | }
389 | ```
390 |
391 | ## Register Device [/v1/Notification/RegisterDevice]
392 |
393 | ### Register device for notifications [POST]
394 |
395 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
396 |
397 | Device ID is generated in-app. Extract it from this call on your device.
398 |
399 | I don't know why you'd use this, either, unless you're the phone.
400 |
401 | + Request (application/json)
402 |
403 | + Headers
404 |
405 | ```
406 | X-ProductVersion: 1.1.0
407 | X-Platform: Android
408 | User-Agent: com.nintendo.znca/1.1.0 (Android/7.0)
409 | Accept: application/json
410 | Authorization: Bearer [Web API access token]
411 | Content-Type: application/json
412 | Content-Length: 190
413 | Host: api-lp1.znc.srv.nintendo.net
414 | Connection: Keep-Alive
415 | Accept-Encoding: gzip
416 | ```
417 |
418 | + Body
419 |
420 | ```json
421 | {
422 | "parameter": {
423 | "registrationToken":"[Device ID]"
424 | }
425 | }
426 | ```
427 |
428 | + Response 200 (application/json)
429 |
430 | + Body
431 |
432 | ```json
433 | {
434 | "correlationId":"a7c8abce-e0427bfb",
435 | "result": {},
436 | "status":0
437 | }
438 | ```
439 |
440 | ## Join VOIP [/v1/Voip/Join]
441 |
442 | ### Join VoIP. [POST]
443 |
444 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
445 |
446 | Device ID is generated in-app. Extract it from [POST /v1/Notification/RegisterDevice](#RegisterDevice) on your device.
447 |
448 | + Request (application/json)
449 |
450 | + Headers
451 |
452 | ```
453 | X-ProductVersion: 1.1.0
454 | X-Platform: Android
455 | User-Agent: com.nintendo.znca/1.1.0 (Android/7.0)
456 | Accept: application/json
457 | Authorization: Bearer [Web API Access Token]
458 | Content-Type: application/json; charset=utf-8
459 | Content-Length: 230
460 | Host: api-lp1.znc.srv.nintendo.net
461 | Connection: Keep-Alive
462 | Accept-Encoding: gzip
463 | ```
464 |
465 | + Body
466 |
467 | ```json
468 | {
469 | "parameter": {
470 | "id": 6088424361558016,
471 | "deviceIdentifier": "[Device ID]",
472 | "muteUserIds": null
473 | }
474 | }
475 | ```
476 |
477 | + Response 200 (application/json)
478 |
479 | + Body
480 |
481 | ```json
482 | {
483 | "result": {
484 | "remoteKeyHex": "a61216832df4c22914c2a976730d399b75cd0f0f247f38f45781945c7cc8",
485 | "remoteSsrc": 1151231983,
486 | "localKeyHex": "922509928cb51eb163a4b4feff7339ef1f1b23f23556d4eae161128a6e61",
487 | "channelId": 0,
488 | "remotePort": 2001,
489 | "localSsrc": 685664239,
490 | "remoteHost": "104.154.86.184"
491 | },
492 | "status": 0,
493 | "correlationId": "bc3021dd-528df2ad"
494 | }
495 | ```
496 |
497 | ## Get VOIP configuration [/v1/Voip/GetConfig]
498 |
499 | ### Get VoIP configuration [POST]
500 |
501 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
502 |
503 | + Request (application/json)
504 |
505 | + Headers
506 |
507 | ```
508 | X-ProductVersion: 1.1.0
509 | X-Platform: Android
510 | User-Agent: com.nintendo.znca/1.1.0 (Android/7.0)
511 | Accept: application/json
512 | Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJmNDE3ZTF0aWJqcWQ5MWNoOTl1NDlpd3o1c245Y2h5MyIsInN1YiI6NjQwMzE2MDMwMjE1NzgyNCwiaXNzIjoiYXBpLWxwMS56bmMuc3J2Lm5pbnRlbmRvLm5ldCIsImlhdCI6MTUwNzQyNDU4MywidHlwIjoiaWRfdG9rZW4iLCJleHAiOjE1MDc0MzE3ODN9.MHZxeCuV_cWm-9IyXXtmMDiLaS316tPjUg1v6B9aBtg
513 | Content-Type: application/json; charset=utf-8
514 | Content-Length: 230
515 | Host: api-lp1.znc.srv.nintendo.net
516 | Connection: Keep-Alive
517 | Accept-Encoding: gzip
518 | ```
519 |
520 | + Body
521 |
522 | ```json
523 | {
524 | "parameter": {
525 | "platform": "Android",
526 | "model": "SM-G935U",
527 | "product": "hero2qlteue",
528 | "device": "hero2qlteue",
529 | "manufacturer": "samsung",
530 | "versionRelease": "7.0",
531 | "versionSdkInt": 24
532 | }
533 | }
534 | ```
535 |
536 | + Response 200 (application/json)
537 |
538 | + Body
539 |
540 | ```json
541 | {
542 | "status": 0,
543 | "correlationId": "d806c612-3f51520f",
544 | "result": {
545 | "androidAudioMode": 3,
546 | "smaec": 1,
547 | "androidRecordingPreset": 4,
548 | "smaecEc": true,
549 | "androidStreamType": 0
550 | }
551 | }
552 | ```
553 |
554 | ## Leave VOIP [/v1/Voip/Leave]
555 |
556 | ### Leave VoIP [POST]
557 |
558 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
559 |
560 | Device ID is generated in-app. Extract it from [POST /v1/Notification/RegisterDevice](#RegisterDevice) on your device.
561 |
562 | ID should be the group ID, obtained via [POST /v1/Event/List](#GetEventList)
563 |
564 | + Request (application/json)
565 |
566 | + Headers
567 |
568 | ```
569 | X-ProductVersion: 1.1.0
570 | X-Platform: Android
571 | User-Agent: com.nintendo.znca/1.1.0 (Android/7.0)
572 | Accept: application/json
573 | Authorization: Bearer [Web API Access Token]
574 | Content-Type: application/json; charset=utf-8
575 | Content-Length: 230
576 | Host: api-lp1.znc.srv.nintendo.net
577 | Connection: Keep-Alive
578 | Accept-Encoding: gzip
579 | ```
580 |
581 | + Body
582 |
583 | ```json
584 | {
585 | "parameter": {
586 | "id": 5123588421058560,
587 | "deviceIdentifier": "[Device ID]"
588 | }
589 | }
590 | ```
591 |
592 | + Response 200 (application/json)
593 |
594 | + Body
595 |
596 | ```json
597 | {
598 | "result": {},
599 | "status": 0,
600 | "correlationId": "85906060-9e307e23"
601 | }
602 | ```
603 |
604 | ## Obtain friends list [/v1/User/List]
605 |
606 | ### Obtain Friends List [POST]
607 |
608 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
609 |
610 | + Request
611 |
612 | + Headers
613 |
614 | ```
615 | X-ProductVersion: 1.1.0
616 | X-Platform: Android
617 | User-Agent: com.nintendo.znca/1.1.0 (Android/7.0)
618 | Accept: application/json
619 | Authorization: Bearer [Web API Access Token]
620 | Content-Type: application/json; charset=utf-8
621 | Content-Length: 230
622 | Host: api-lp1.znc.srv.nintendo.net
623 | Connection: Keep-Alive
624 | Accept-Encoding: gzip
625 | ```
626 |
627 | + Response 200 (application/json)
628 |
629 | + Body
630 |
631 | ```json
632 | {
633 | "status": 0,
634 | "correlationId": "fffa6813-70e8fde9",
635 | "result": [
636 | {
637 | "name": "Virepri",
638 | "isServiceUser": true,
639 | "supportId": "0664-9173-0838-4959-9123-9",
640 | "isFriend": false,
641 | "lastSeenAt": 0,
642 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/ae160604808ae5ad",
643 | "id": 6403160302157824,
644 | "isFavoriteFriend": false
645 | },
646 | {
647 | "name": "Centzilius",
648 | "isServiceUser": true,
649 | "isFriend": true,
650 | "lastSeenAt": 0,
651 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/3b0937a3e09e6517",
652 | "id": 6330250325655552,
653 | "isFavoriteFriend": false
654 | },
655 | {
656 | "name": "TPoS-Shin",
657 | "isServiceUser": true,
658 | "isFriend": true,
659 | "lastSeenAt": 0,
660 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/26f4a1e2a08ee69b",
661 | "id": 5409588421591040,
662 | "isFavoriteFriend": false
663 | },
664 | {
665 | "name": "AJ",
666 | "isServiceUser": false,
667 | "isFriend": true,
668 | "lastSeenAt": 0,
669 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/aa25d9cdc3f03350",
670 | "id": 0,
671 | "isFavoriteFriend": false
672 | },
673 | {
674 | "name": "Some1CP",
675 | "isServiceUser": true,
676 | "isFriend": true,
677 | "lastSeenAt": 0,
678 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/4a4af58feed30a0e",
679 | "id": 6612396567166976,
680 | "isFavoriteFriend": false
681 | },
682 | {
683 | "name": "Atomic",
684 | "isServiceUser": true,
685 | "isFriend": true,
686 | "lastSeenAt": 0,
687 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/b55b17be67346d04",
688 | "id": 4877687744102400,
689 | "isFavoriteFriend": true
690 | },
691 | {
692 | "name": "Shags",
693 | "isServiceUser": false,
694 | "isFriend": true,
695 | "lastSeenAt": 0,
696 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/34924d955f2dbe21",
697 | "id": 0,
698 | "isFavoriteFriend": false
699 | },
700 | {
701 | "name": "acid treez",
702 | "isServiceUser": true,
703 | "isFriend": true,
704 | "lastSeenAt": 0,
705 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/c8e8ed04dfb82b52",
706 | "id": 5830558567366656,
707 | "isFavoriteFriend": false
708 | },
709 | {
710 | "name": "Arsanus",
711 | "isServiceUser": false,
712 | "isFriend": true,
713 | "lastSeenAt": 0,
714 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/1b98b0d3e78dffb0",
715 | "id": 0,
716 | "isFavoriteFriend": true
717 | },
718 | {
719 | "name": "Vertsix",
720 | "isServiceUser": false,
721 | "isFriend": true,
722 | "lastSeenAt": 0,
723 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/c1765003c338efc8",
724 | "id": 0,
725 | "isFavoriteFriend": false
726 | },
727 | {
728 | "name": "гεd☆sкγε",
729 | "isServiceUser": true,
730 | "isFriend": true,
731 | "lastSeenAt": 0,
732 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/d5152ad313c572d4",
733 | "id": 5164065190051840,
734 | "isFavoriteFriend": false
735 | },
736 | {
737 | "name": "King Udyr",
738 | "isServiceUser": true,
739 | "isFriend": true,
740 | "lastSeenAt": 0,
741 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/495508ab65149923",
742 | "id": 6223255610327040,
743 | "isFavoriteFriend": false
744 | },
745 | {
746 | "name": "UncleBones",
747 | "isServiceUser": true,
748 | "isFriend": true,
749 | "lastSeenAt": 0,
750 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/8609da5bf75c1ae8",
751 | "id": 5333171474268160,
752 | "isFavoriteFriend": true
753 | },
754 | {
755 | "name": "FishPhd",
756 | "isServiceUser": true,
757 | "isFriend": true,
758 | "lastSeenAt": 0,
759 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/fa7ee5bbdd1730be",
760 | "id": 6208096925908992,
761 | "isFavoriteFriend": false
762 | },
763 | {
764 | "name": "SillyChip",
765 | "isServiceUser": false,
766 | "isFriend": true,
767 | "lastSeenAt": 0,
768 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/2d62166c88c180a7",
769 | "id": 0,
770 | "isFavoriteFriend": true
771 | },
772 | {
773 | "name": "ramtower",
774 | "isServiceUser": true,
775 | "isFriend": true,
776 | "lastSeenAt": 0,
777 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/839f84e45d6c503c",
778 | "id": 5876604337127424,
779 | "isFavoriteFriend": true
780 | },
781 | {
782 | "name": "Kev | HDK",
783 | "isServiceUser": true,
784 | "isFriend": true,
785 | "lastSeenAt": 0,
786 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/ec9c900c5bd98a18",
787 | "id": 5928458282598400,
788 | "isFavoriteFriend": false
789 | },
790 | {
791 | "name": "Weeee",
792 | "isServiceUser": false,
793 | "isFriend": true,
794 | "lastSeenAt": 0,
795 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/fc40cf8eab622bf4",
796 | "id": 0,
797 | "isFavoriteFriend": false
798 | },
799 | {
800 | "name": "Sora",
801 | "isServiceUser": true,
802 | "isFriend": true,
803 | "lastSeenAt": 1506986817,
804 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/ec0cd600097a8dec",
805 | "id": 6525512310587392,
806 | "isFavoriteFriend": true
807 | }
808 | ]
809 | }
810 | ```
811 |
812 | ## Show User Fast [/v1/User/ShowFast]
813 |
814 | ### Show User Fast (for VoIP) [POST]
815 |
816 | Web API Access Token should be webApiServerCredential["accesstoken"] from [POST /v1/Account/Login](#LoginAccount).
817 |
818 | ID should be a user ID
819 |
820 | + Request
821 |
822 | + Headers
823 |
824 | ```
825 | X-ProductVersion: 1.1.0
826 | X-Platform: Android
827 | User-Agent: com.nintendo.znca/1.1.0 (Android/7.0)
828 | Accept: application/json
829 | Authorization: Bearer [Web API Access Token]
830 | Content-Type: application/json; charset=utf-8
831 | Content-Length: 230
832 | Host: api-lp1.znc.srv.nintendo.net
833 | Connection: Keep-Alive
834 | Accept-Encoding: gzip
835 | ```
836 |
837 | + Body
838 |
839 | ```json
840 | {
841 | "parameter":{
842 | "id":5409588421591040
843 | }
844 | }
845 | ```
846 |
847 | + Response 200 (application/json)
848 |
849 | + Body
850 |
851 | ```json
852 | {
853 | "result": {
854 | "id": 5409588421591040,
855 | "name": "TPoS-Shin",
856 | "imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/26f4a1e2a08ee69b"
857 | },
858 | "correlationId": "b9917772-b68d5bff",
859 | "status": 0
860 | }
861 | ```
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Reverse Engineered Nintendo Switch App REST API
2 |
3 | ## Introduction
4 |
5 | This is documentation of the REST APIs used for the Nintendo Switch app, and embedded Splatoon 2 web app.
6 |
7 | All testing was done on an iPhone 7 running iOS 10.3.3 using version 1.0.4 of the Nintendo Switch app on 07/30/17. I reverse-engineered using [mitmproxy](https://mitmproxy.org). It was quite easy as the app does not use cert-pinning at all. I have not tested using the Android app at all, but I would assume that everything is identical (besides obvious user-agent differences). I am using a US account with the language set to English. There may be small differences for other regions.
8 |
9 | A [Paw](https://paw.cloud) project is included for macOS users which should help tinkering with the API. I highly recommend trying this out first to figure out how the API works. Take a look at the environment variables to see what you need to fill in. Once you fill in `Client ID`, `Login Page Token Code`, `Login Page Token Code Verifier`, and `Birthday` you can execute the auth requests in order and you should be good to go.
10 |
11 | Note: I recommend setting the `User-Agent` on all requests to the Splatoon 2 API to the following string to blend in. There doesn't appear to be any checking for this but better safe than sorry. `Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60`
12 |
13 | ## Blueprints
14 | * [Nintendo Account](NintendoAccountBlueprint.md)
15 | * [Nintendo Switch](SwitchBlueprint.md)
16 | * [Splatoon 2](Splatoon2Blueprint.md)
17 |
18 | ## Open Source Components
19 |
20 | If you are curious about the open source components used in the app, I have compiled them [here](OpenSource.md).
21 |
22 | ## Authentication Steps
23 |
24 | 1. Visit authorization link in browser
25 |
26 | This page is an HTML page which loads the auth flow which you would normally see first when logging into the app. Follow through the flow by logging in with an account.
27 |
28 | https://accounts.nintendo.com/connect/1.0.0/authorize?state=[state here]&redirect_uri=[... continues]
29 |
30 | I currently have no idea how this URL is generated. I recommend signing out of the Switch app, then sign back in and open the sign flow link in Safari. You can then open it on your computer and follow from there.
31 |
32 | Once you sign in, you will be redirected to a page like `npf71b963c1b7b6d119://auth#session_state=[SessionStateReturnedHere]&session_token_code=[codehere]&state=[StateReturnedHere]`
33 |
34 | 2. Get a session token
35 |
36 | Extract the session_state and state from that url, and request from [POST /connect/1.0.0/api/session_token](NintendoAccountBlueprint.md#GetSessionToken)
37 |
38 | 3. Get a service access token
39 |
40 | Make a request to [POST /connect/1.0.0/api/token](NintendoAccountBlueprint.md#GetServiceToken) using `session_token` from 2.
41 |
42 | 4. Login to account
43 |
44 | Make a request to [POST /v1/Account/Login](SwitchBlueprint.md#LoginAccount). Use `id_token` from 3.
45 |
46 | 5. Get game list
47 |
48 | Use your access token to retrieve the game list from [GET /v1/Game/ListWebServices](SwitchBlueprint.md#GetGameList). Use `webApiServerCredential["accesstoken"]` from 4.
49 |
50 | 6. Get access token for Splatoon
51 |
52 | Make a request to [GET /v1/Game/GetWebServiceToken](SwitchBlueprint.md#GetGameWebServiceToken). Use the ID of Splatoon 2 from 5 and `webApiServerCredential["accesstoken"]` from 4.
53 |
54 | 7. Get cookie to use for splatoon requests
55 |
56 | Make a request to [GET /](Splatoon2Blueprint.md#GetHomepage). Use the `accessToken` from 6.
57 |
58 | 8. Play with the Splatoon 2 API
59 |
60 | You can now make any request from the [Splatoon 2 API](Splatoon2Blueprint.md) using the cookie retrieved from 7. Have fun!
61 |
--------------------------------------------------------------------------------