Nintendo Switch Online API - tkgstrator/Salmonia3 GitHub Wiki
Session Token
Access Token 取得のための Session Token を取得します。
リクエスト
パラメータ | 値 |
---|---|
Method | POST |
URL | https://accounts.nintendo.com/connect/1.0.0/api/session_token |
User-Agent | OnlineLounge/2.0.0 NASDKAPI iOS |
client_id=71b963c1b7b6d119&session_token_code=eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLm5pbnRlbmRvLmNvbSIsInN0YzpzY3AiOlswLDgsOSwxNywyM10sImp0aSI6IjM1NzQ1MTg5MTkxIiwic3RjOmMiOiJ0ejdaMGhfM2RLMTBYLTc5SlREWUUyaG5seGU1dWhYd0tsUldoQUdBb1ZZIiwic3RjOm0iOiJTMjU2Iiwic3ViIjoiNWFlOGY3YTc4YjBjY2E0ZCIsInR5cCI6InNlc3Npb25fdG9rZW5fY29kZSIsImV4cCI6MTYxOTQ3OTE0OSwiYXVkIjoiNzFiOTYzYzFiN2I2ZDExOSIsImlhdCI6MTYxOTQ3ODU0OX0.XSFscPYMGbcaLLJxBA-fIO0zzt1bWs4X39oZGOs4jrI&session_token_code_verifier=RwKTiEojlJbQInnPCHBitkNHehgICjFsstWUvOkGQibeuukvXx
client_id
の値は固定値です。
JSON ではなく Form-Data で Body を送信します。
エラー
// 400
{
"error_description": "The provided session_token_code is expired",
"error": "invalid_request"
}
レスポンス
{
"code": "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLm5pbnRlbmRvLmNvbSIsInN1YiI6IjVhZThmN2E3OGIwY2NhNGQiLCJleHAiOjE2MTk0ODIxNTUsImlhdCI6MTYxOTQ3ODU1NSwidHlwIjoiY29kZSIsImF1ZCI6IjcxYjk2M2MxYjdiNmQxMTkiLCJhYzpzY3AiOlswLDgsOSwxNywyM10sImp0aSI6IjM1NzQ1MTYxODQzIn0.vT1aaYdqHaAinY0BKGDeG2cAUqS5DOndH02keQxZXxw",
"session_token": "eyJhbGciOiJIUzI1NiJ9.eyJzdDpzY3AiOlswLDgsOSwxNywyM10sInN1YiI6IjVhZThmN2E3OGIwY2NhNGQiLCJleHAiOjE2ODI1NTA1NTUsImlzcyI6Imh0dHBzOi8vYWNjb3VudHMubmludGVuZG8uY29tIiwidHlwIjoic2Vzc2lvbl90b2tlbiIsImlhdCI6MTYxOTQ3ODU1NSwiYXVkIjoiNzFiOTYzYzFiN2I2ZDExOSIsImp0aSI6IjUwNjgwMjkzODEifQ.CwI0tqAv186pEgo7HKn_q--l8fB-jmwFu6iJNNvY_W8"
}
Access Token
Nintendo Switch Online のサービスに接続するための Access Token を取得します。
リクエスト
パラメータ | 値 |
---|---|
Method | POST |
URL | https://accounts.nintendo.com/connect/1.0.0/api/token |
User-Agent | OnlineLounge/2.0.0 NASDKAPI iOS |
{
"client_id": "71b963c1b7b6d119",
"session_token": "eyJhbGciOiJIUzI1NiJ9.eyJzdDpzY3AiOlswLDgsOSwxNywyM10sInN1YiI6IjVhZThmN2E3OGIwY2NhNGQiLCJleHAiOjE2ODI1NTA1NTUsImlzcyI6Imh0dHBzOi8vYWNjb3VudHMubmludGVuZG8uY29tIiwidHlwIjoic2Vzc2lvbl90b2tlbiIsImlhdCI6MTYxOTQ3ODU1NSwiYXVkIjoiNzFiOTYzYzFiN2I2ZDExOSIsImp0aSI6IjUwNjgwMjkzODEifQ.CwI0tqAv186pEgo7HKn_q--l8fB-jmwFu6iJNNvY_W8",
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer-session-token"
}
client_id
, grant_type
の値は固定値です。
エラー
// 400
// セッショントークンが誤っている場合
{
"error_description": "The provided grant is invalid",
"error": "invalid_grant"
}
// 400
// クライアントIDが誤っている場合
{
"error": "invalid_client",
"error_description": "Client authentication failed"
}
// 400
// フォーマットが正しくない場合
{
"error_description": "The request does not satisfy the schema",
"error": "invalid_request"
}
レスポンス
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg1ZTNjN2FkLTBlMTQtNDIxMi1hZTg5LTExMjIwZmM3MDMzYSIsImprdSI6Imh0dHBzOi8vYWNjb3VudHMubmludGVuZG8uY29tLzEuMC4wL2NlcnRpZmljYXRlcyJ9.eyJhdWQiOiI3MWI5NjNjMWI3YjZkMTE5Iiwic3ViIjoiNWFlOGY3YTc4YjBjY2E0ZCIsImp0aSI6IjgyYzUzM2NjLWJkNzQtNDkwOC04NjVkLTAwOWM2MGM5MWY0NiIsImFjOnNjcCI6WzAsOCw5LDE3LDIzXSwiaWF0IjoxNjE5NDc4NTU2LCJpc3MiOiJodHRwczovL2FjY291bnRzLm5pbnRlbmRvLmNvbSIsImFjOmdydCI6NjQsInR5cCI6InRva2VuIiwiZXhwIjoxNjE5NDc5NDU2fQ.lXFbLqUIVFegSHzFvH3aLp1HOB3iwajs107YLt0MePrcqLDvmTpu_MNewGrnpX0BAAfB79lDGt7MFmi6HKcIQxacaExP7tIHYowmHBU5eDM4VSbZJq7LP8SMftRAcvDA1-bNOr3_uFhqtXP18mDDZRYfB7lEXVbcj3sdkNPrWlyic-vHwZTQ-qwMTWPLZzYwwGjage1OfpRwwC-YrU0hpgg-DIj5yTN-eCrwkp48rsQU_MOCw5--HRW90x-LU6rjK7_CgHG3Qafz4pvuYmRzDl3WWtoSGUdZCh6wF3SKta0GzReZIIic-iog3eo21vgagWbnEWz_86iYjsF9DAnPzQ",
"scope": ["openid", "user", "user.birthday", "user.mii", "user.screenName"],
"token_type": "Bearer",
"id_token": "eyJqa3UiOiJodHRwczovL2FjY291bnRzLm5pbnRlbmRvLmNvbS8xLjAuMC9jZXJ0aWZpY2F0ZXMiLCJraWQiOiI1ZTkwMDRlOC1mMDNiLTRjZTEtYmU2Zi1jNzdlZTM4YTA4MjEiLCJhbGciOiJSUzI1NiJ9.eyJleHAiOjE2MTk0Nzk0NTYsImNvdW50cnkiOiJKUCIsInR5cCI6ImlkX3Rva2VuIiwiYXRfaGFzaCI6InVHUzZvQkJRQUJEN2hWMHJOdnpiS2ciLCJpYXQiOjE2MTk0Nzg1NTYsImlzcyI6Imh0dHBzOi8vYWNjb3VudHMubmludGVuZG8uY29tIiwic3ViIjoiNWFlOGY3YTc4YjBjY2E0ZCIsImF1ZCI6IjcxYjk2M2MxYjdiNmQxMTkiLCJqdGkiOiI0NmJjZmRiMy00MmUyLTRmM2UtYjhlYy1jY2YyYzNmNWZjNGYifQ.qy0QMaQ_QsCajYZkkuHlfRtWETFSUtxKfddtAsRT2EBTGpBxNV2p3VsKtWnNHduH5ZvFKa978sqBmTqjSzfPDJEF2T4JciuXvlQL73zlSPN2GxmI65K030nyvGYebd_d7XRBEEtTKGTWuhHmkk_nglToBlKWr0QG23dWGTA2phJUUU2BKiB44Gdbcq4Fopdtu9wqhtxN2lWc_OtpdHaVlmuQfOXqNHI5ohHFp4wzjrsIUOzUTVtq3Br52c1umWoFxOxnlIHdiNz1bNGWbtY9YfJHdEe1PECyj_oB8cQgkz4DDLHHVFGYz5shtGLZ1JlewVERMQw4JzBD1SiNx1FVWw",
"expires_in": 900
}
User Info
Access Token からユーザ情報を取得する API です。
Splatoon Token 取得時に生年月日などを渡す必要があるため取得しますが、生年月日などは適当に設定してもリクエストは通ります。ここで取得した生年月日をそのまま使うと 13 歳以下のアカウントの iksm session が取得できなくなるため、この API を叩く意味は実はあまりありません。
リクエスト
パラメータ | 値 |
---|---|
Method | GET |
URL | https://api.accounts.nintendo.com/2.0.0/users/me |
User-Agent | OnlineLounge/2.0.0 NASDKAPI iOS |
Authorization | Bearer |
GET リクエストなのでパラメータは存在しません。
レスポンス
{
"emailOptedIn": false,
"analyticsPermissions": {
"targetMarketing": {
"updatedAt": 1595545468,
"permitted": true
},
"internalAnalysis": {
"permitted": true,
"updatedAt": 1595545468
}
},
"analyticsOptedIn": true,
"emailOptedInUpdatedAt": 1572596527,
"gender": "female",
"nickname": "Salmonia",
"screenName": "sa•••@g•••• / sal•••",
"id": "5ae8f7a78b0cca4d",
"analyticsOptedInUpdatedAt": 1595545468,
"clientFriendsOptedInUpdatedAt": 1572596527,
"region": null,
"language": "en-US",
"clientFriendsOptedIn": true,
"country": "JP",
"birthday": "1996-09-01",
"eachEmailOptedIn": {
"deals": {
"optedIn": false,
"updatedAt": 1572596527
},
"survey": {
"updatedAt": 1572596527,
"optedIn": false
}
},
"candidateMiis": [],
"createdAt": 1572596527,
"updatedAt": 1612832536,
"timezone": {
"utcOffset": "+09:00",
"name": "Asia/Tokyo",
"id": "Asia/Tokyo",
"utcOffsetSeconds": 32400
},
"emailVerified": true,
"isChild": false,
"mii": null
}
Splatoon Token
Splatoon 用の Session Token を発行します。パラメータに f が必要なため s2s API と flapg API を使って f の値を計算する必要があります。
ここではまだ Bearer の値がないため、空文字を指定して大丈夫です。
リクエスト
パラメータ | 値 |
---|---|
Method | POST |
URL | https://api-lp1.znc.srv.nintendo.net/v3/Account/Login |
X-ProductVersion | 2.0.0 |
X-Platform | iOS |
Authorization | Bearer |
{
"parameter": {
"id": 5741031244955648,
"f": "9e4e5b2e13f46e399adb5f390fd95b2b78de7e3d7e886633f8d16c479382d5e5d44caca68bc19351fe1d0b69c7",
"requestId": "96A80E43-CC15-4724-9196-31708BC56D1D",
"timestamp": 1648687145,
"registrationToken": "fK0khI0DhU8KmMKxX6oixI:APA91bEcKhiHi4acYjs495cIih46knhphM1SEUJo7eBu4cCPXfBSK82XnpnDkCrowl9DWN8v7hqwN2eDnFaclhnOyUKE7N1YXtwtps4ES7oQPMQmFqb86NK_V0hblS2ojYoDpSOa7mOD"
},
"requestId": "25390584-A6B6-4E4E-8AD8-9C10ABFAB440"
}
2.0.0から何故かrequestId
が二つ必要になりました。ちなみに指定してもレスポンスのcorrelationId
が変わるだけで必須ではないみたい。
エラー
// 200
// Headerのフォーマットが正しくない
// ステータスコードは200なのに実質中身が400エラーなので注意
{
"errorMessage": "Bad request.",
"status": 9400,
"correlationId": "56913522-00755d2d"
}
// 200
// X-ProductVersionが低い
{
"correlationId": "b0f908ec-8363cb18",
"errorMessage": "Upgrade required.",
"status": 9427
}
// 200
// naIdTokenの有効期限切れ
{
"status": 9403,
"errorMessage": "Invalid token.",
"correlationId": "33f960d7-324c66c2"
}
レスポンス
旧フォーマット
{
"result": {
"webApiServerCredential": {
"expiresIn": 7200,
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjQ3MzczNjA4MzEzODE1MDQsImV4cCI6MTYxOTQ4NTc1OCwiYXVkIjoiZjQxN2UxdGlianFkOTFjaDk5dTQ5aXd6NXNuOWNoeTMiLCJ0eXAiOiJpZF90b2tlbiIsImlhdCI6MTYxOTQ3ODU1OCwibWVtYmVyc2hpcCI6eyJhY3RpdmUiOnRydWV9LCJpc3MiOiJhcGktbHAxLnpuYy5zcnYubmludGVuZG8ubmV0In0.tjMhqXiaiO4keh5x17xJ1NKMxXw97wZ9xaJGYYOuB2U"
},
"user": {
"membership": {
"active": true
},
"id": 4737360831381504,
"name": "まゆしぃのかみ",
"supportId": "0457-8405-4211-3149-1927-5",
"imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/6d55aa14478fbb82"
},
"firebaseCredential": {
"expiresIn": 3600,
"accessToken": ""
}
},
"status": 0,
"correlationId": "22bf5c73-fc96deb5"
}
新フォーマット
{
"status": 0,
"result": {
"user": {
"id": 6445457169973248,
"nsaId": "91d160aa84e88da6",
"imageUri": "https://cdn-image-e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1/430d0e57d74d2366",
"name": "めがねっこをあがめよ",
"supportId": "1050-7285-6911-2261-7766-2",
"isChildRestricted": false,
"etag": "\"b956035ff2461637\"",
"links": {
"nintendoAccount": {
"membership": {
"active": true
}
},
"friendCode": {
"regenerable": true,
"regenerableAt": 1513589500,
"id": "1384-4712-4713"
}
},
"permissions": {
"presence": "FRIENDS"
},
"presence": {
"state": "OFFLINE",
"updatedAt": 1648654440,
"logoutAt": 1648654440,
"game": {}
}
},
"webApiServerCredential": {
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc0NoaWxkUmVzdHJpY3RlZCI6ZmFsc2UsIm1lbWJlcnNoaXAiOnsiYWN0aXZlIjp0cnVlfSwiYXVkIjoiZjQxN2UxdGlianFkOTFjaDk5dTQ5aXd6NXNuOWNoeTMiLCJleHAiOjE2NDg2OTYwNzQsImlhdCI6MTY0ODY4ODg3NCwiaXNzIjoiYXBpLWxwMS56bmMuc3J2Lm5pbnRlbmRvLm5ldCIsInN1YiI6NjQ0NTQ1NzE2OTk3MzI0OCwidHlwIjoiaWRfdG9rZW4ifQ.UjXgsX4lPi5_3lYCrQh475UkSho2FbsESEsJRw19X_Q",
"expiresIn": 7200
},
"firebaseCredential": {
"accessToken": "",
"expiresIn": 3600
}
},
"correlationId": "E6293799-06DC-4B73-BF7B-3EEBD7F14511-0ec95b4f"
}
かなりデータが変更されて、ログイン情報やフレンドコードなどが見れるようになりました。
Splatoon Access Token
Splatoon 用の Access Token を発行します。パラメータに f が必要なため s2s API と flapg API を使って f の値を計算する必要があります。
Bearer には Splatoon Token を指定する必要があります。
リクエスト
パラメータ | 値 |
---|---|
Method | POST |
URL | https://api-lp1.znc.srv.nintendo.net/v2/Game/GetWebServiceToken |
X-ProductVersion | 2.0.0 |
X-Platform | iOS |
Authorization | Bearer |
{
"parameter": {
"registrationToken": "fK0khI0DhU8KmMKxX6oixI:APA91bEcKhiHi4acYjs495cIih46knhphM1SEUJo7eBu4cCPXfBSK82XnpnDkCrowl9DWN8v7hqwN2eDnFaclhnOyUKE7N1YXtwtps4ES7oQPMQmFqb86NK_V0hblS2ojYoDpSOa7mOD",
"requestId": "70ADAB23-9FEE-4C16-8B2D-85EE2F690502",
"timestamp": 1648689090,
"id": 5741031244955648,
"f": "462b2175be068ecc445a869f19fbff1f0a2962b92f405c0eec21a43909c0c17bccf0e6aa9cf7fb77b31bf208a8"
},
"requestId": "BB294B86-5C4A-433C-86A9-B7E54742542E"
}
こちらもrequestId
を二つ指定できるようになりました。
レスポンス
{
"status": 0,
"result": {
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImI3ZXhudVJhTG05SlpaRWxHMEl5RExnMGk1MCIsImprdSI6Imh0dHBzOi8vYXBpLWxwMS56bmMuc3J2Lm5pbnRlbmRvLm5ldC92MS9XZWJTZXJ2aWNlL0NlcnRpZmljYXRlL0xpc3QifQ.eyJpc0NoaWxkUmVzdHJpY3RlZCI6ZmFsc2UsImF1ZCI6IjV2bzJpMmtteng2cHMxbDF2anNqZ25qczk5eW16Y3cwIiwiZXhwIjoxNjQ4Njk2MjkxLCJpYXQiOjE2NDg2ODkwOTEsImlzcyI6ImFwaS1scDEuem5jLnNydi5uaW50ZW5kby5uZXQiLCJqdGkiOiI1YzUyMzA0Yy1kYjYyLTRlN2UtYjk2NS00MGE0OWJjNDNiNDEiLCJzdWIiOjY0NDU0NTcxNjk5NzMyNDgsImxpbmtzIjp7Im5ldHdvcmtTZXJ2aWNlQWNjb3VudCI6eyJpZCI6IjkxZDE2MGFhODRlODhkYTYifX0sInR5cCI6ImlkX3Rva2VuIiwibWVtYmVyc2hpcCI6eyJhY3RpdmUiOnRydWV9fQ.Ba-ZzlxhReetMFpB7lHFJ_a4OW4C1CohLV3JSWjoD2V5Tj4Sl5mcPt7mSHYDkmIX_K2hHwrJNoCWxZivpamUq_rkPf8NXAwcOM0OtaqHfvVO_6knuiJ7A2N0z55T3C1h6ww2bNiwKgZ0eNcyys2O8WtKn0aNzBZOi8UiVfW2EwiN7su7IcZJrOh0f8e-IB3Yo6PKzucq1O0vEgyBAW4R2RgAstSQuCZf1gpxCmeO3IUDs4cmgQ8fawqq1QtHlg7soXEryB7FXk1xO6aUNoIss-zGJWcvINNwpf7XKtgnhaokvLT9bIqRIjWisa_9Lszb6tXkr4N_Nu7TyqF7Nij8sQ",
"expiresIn": 7200
},
"correlationId": "BB294B86-5C4A-433C-86A9-B7E54742542E-119883ef"
}
エラー
// 200
{
"status": 9400,
"correlationId": "02094d49-a2f6b0f1",
"errorMessage": "Bad request."
}
// 200
// Splatoon Tokenが有効期限切れ
{
"status": 9404,
"errorMessage": "Token expired.",
"correlationId": "0f217900-92b9041b"
}
// 200
// Bearer Tokenがセットされていない
{
"correlationId": "b7b6ca68-a4f79aaf",
"status": 9406,
"errorMessage": "Unauthorized."
}
// 200
// X-ProductVersionが低い
{
"correlationId": "b0f908ec-8363cb18",
"errorMessage": "Upgrade required.",
"status": 9427
}
API
// 403
{
"message": "api_error_authentication_error",
"code": "AUTHENTICATION_ERROR"
}
// 403
Forbidden
フレンドリスト
パラメータ | 値 |
---|---|
Method | POST |
URL | https://api-lp1.znc.srv.nintendo.net/v3/Friend/List |
必要なのはAuthorization Bearer
のみ。SplatoonTokenで見る感じなので有効期限は多分7200秒。
{
"status": 9404,
"errorMessage": "Token expired.",
"correlationId": "A6AAFDA0-E23B-45EA-83B7-1211ECA1404E-168c6990"
}