Docs
Login Kit with QR Code
Overview
This doc will provide instruction on how to integrate QR code authorization capability with TikTok in your web application. This will enable your app to access TikTok user data within approved scopes using obtained access token.
Prerequisites
Please obtain a client key and a client secret from the developer portal on https://developers.tiktok.com under "My apps".
Integration Guide
On the server side, the main functionality of your web app is:
- Request QR code url, generate a client_ticket, insert client_ticket to QR code url, render the url and display to user
- Loop to check QR code status and refresh/disable it accordingly
- Once QR code status is changed to 'confirmed', a valid authorization code is retrieved
- Request access token and refresh token (used to refresh access token) from Tiktok using the authorization code and client key
- Notify the user of authorization success/failure
- Use the access token to access proper user data, and use the refresh token to prolong the access token expiration time
- Read document "Login Kit/ Manage User Access Tokens" for detail about step 3-6. Read Appendix for detail about how to use "client_ticket"
APIs
Get QR Code Endpoint
GEThttps://open-api.tiktok.com/v0/oauth/get_qrcode
Description
Request QR code from TikTok
Request
Request Query
Key | Type | Description | Example | Required |
client_key | string | Client key provided by TikTok | aw7nk86b7czitwc9 | true |
scope | string | Comma-separated scope name. Need to be approved first | user.info.basic,user.info.username | true |
next | string | Callback url. Domain needs to be approved along with scopes on TikTok for Developers | https://calllback.example.com | true |
state | string | Callback url parameters | key%3Dabc | true |
Example request URL
https://open-api.tiktok.com/v0/oauth/get_qrcode?client_key=aw7ne86e7fzitwc9&scope=user.info.basic&next=https://callback.example.com&state=key%3Dvalue
Response
Response Body
Key | Type | Description | Example |
message | string | Response status | success | error |
data | Response.data Struct | Response body data | N/A |
extra | Response.extra Struct | Extra information for the response | N/A |
Response.data Struct
When the call succeeds, return the following struct. After getting the response, please do following steps:
- Get "scan_qrcode_url" in the response data and generate a string called ticket on your service and store in you service. To generate a ticket you can use any approach you want. For example, you can randomly generate a 8 character string, which contains a-z and 0-9, like "2ncv7awq".
- Inside "scan_qrcode_url", there is a parameter "client_ticket", replace the value with your ticket generated before. For example, "scan_qrcode_url" = "...&client_ticket=tobefilled&..." will be replaced by "scan_qrcode_url" = "...&client_ticket=your_ticket&...".
- Use the modified "scan_qrcode_url" to generate QR code.
- Show the QR code to your users.
This "client_ticket" will be used when calling check_qrcode endpoints. You can look at the Appendix at the bottom of the document to see the whole process of using "client_ticket".
Key | Type | Description | Example |
scan_qrcode_url | string | QR code url, returned when the call is successful | aweme://authorize?authType=100&client_key=abcd1234&client_ticket=tobefilled&... |
token | string | Token used to check QR code status, returned when the call is successful | VJ5JCKGJGRSWNMFWHQH4W5NKY943Q97D |
error_code | int32 | Error code returned when the call is successful | 0 |
When the call fails, return following struct
Key | Type | Description | Example |
description | string | Error description returned when the call is failed | error |
error_code | int32 | Error code returned when the call is failed | 10001 |
Response.extra Struct
Key | Type | Description | Example |
error_detail | string | Details for the error. When the call is successful, the error_detail is empty string. | parameter is invalid. |
logid | int32 | The log ID for this request. | 20211217192600010245241048055EDE71 |
Example Response
Success
{
"data": {
"error_code": 0,
"scan_qrcode_url": "aweme://authorize?authType=100&client_key=abcd1234&client_ticket=tobefilled&...",
"token": "VJ5JCKGJGRSWNMFWHQH4W5NKY943Q97D..."
},
"extra": {
"error_detail": "",
"logid": "20211217192600010245241048055EDE71"
},
"message": "success"
}
Failure
{
"data":{
"description": "error",
"error_code": 10001
},
"extra": {
"error_detail": "error details",
"logid": "20211217192600010245241048055EDE71"
},
"message":"error"
}
Check QR code Endpoint
GEThttps://open-api.tiktok.com/v0/oauth/check_qrcode
Description
Check QR code status
Note
This API should be accessed with poll method in your app server side. After calling get_qrcode endpoint, this API should be called immediately.
Request
Request Query
Key | Type | Description | Example | Required |
client_key | string | Client key provided by TikTok | aw7ne86e7fzitwc9 | true |
scope | string | Comma-separated scope name. Need to be approved first | user.info.basic,user.info.username | true |
next | string | Callback url. Domain needs to be approved along with scopes on TikTok for Developers | https://calllback.example.com | true |
token | string | Token obtained along with QR code | VJ5JCKGJGRSWNMFWHQH4W5NKY943Q97D | true |
Example request URL
https://open-api.tiktok.com/v0/oauth/check_qrcode?client_key=aw7ne86e7fzitwc9&scope=user.info.basic&next=https://callback.example.com&token=VJ5JCKGJGRSWNMFWHQH4W5NKY943Q97D
Response
Response Body
Key | Type | Description | Example |
message | string | Response status | success | error |
data | Response.data Struct | Response body data | N/A |
extra | Response.extra Struct | Extra information for the response | N/A |
Response.data Struct
When the call succeeds, return following struct. After getting the response, you should:
- Checking the status, when the status is confirmed, the authorization code will be appended in the "redirect_url".
- When status is not equal to "expired", checking whether the client_ticket returned in the data struct can be matched with the ticket you have generate after calling get_qrcode API. If they don't match, then drop the response.
- When status is "expired", recall the get_qrcode API.
Key | Type | Description | Example |
client_ticket | string | A string, which is generate in user's service. This is returned when the call is successful. | client_ticket="A23SDWEGsdasd" |
status | string | QR code status | new | expired | scanned | confirmed |
redirect_url | string | Redirect URL appended with authorization code, returned when the status is | https://callback.example.com?code=HOXbXtnAok4qojdOmsHjucm1V1KJrOjYuMnV |
error_code | int32 | Error code returned 0 when the call is successful | 0 |
When the call fails, return the following struct.
Key | Type | Description | Example |
description | string | Error description returned when the call is failed | error |
error_code | int32 | Error code returned when the call is failed | 10001 |
Response.extra Struct
Key | Type | Description | Example |
error_detail | string | Details for the error. When the call is successful, the error_detail is empty string. | parameter is invalid. |
logid | int32 | The log ID for this request. | 20211217192600010245241048055EDE71 |
Example Response
Success
// status = new, wait for user to scan this QR, client_ticket will be empty
{
"data":{
"client_ticket": "",
"error_code" 0,
"status": "new"
},
"extra":{
"error_detail": "",
"logid": "202112132120360102452421962502D468"
},
"message": "success"
}
// status = scanned. should disable the QR code under this scenario
{
"data":{
"client_ticket": "your_ticket_string",
"error_code" 0,
"status": "scanned"
},
"extra":{
"error_detail": "",
"logid": "202112132120360102452421962502D468"
},
"message": "success"
}
// status = confirmed authorization and obtain the code
{
"data":{
"client_ticket": "your_ticket_string",
"error_code" 0,
"status": "comfirmed",
"redirect_url": "https://example.com?code=example_code"
},
"extra":{
"error_detail": "",
"logid": "202112132120360102452421962502D468"
},
"message": "success"
}
// status = expired, should request new QR code under this scenario
{
"data":{
"error_code" 0,
"status": "expired"
},
"extra":{
"error_detail": "",
"logid": "202112132120360102452421962502D468"
},
"message": "success"
}
Failure
{
"data":{
"description": "error",
"error_code": 10001
},
"extra": {
"error_detail": "error details",
"logid": "202112131904550102510041850CDE9528"
},
"message":"error"
}
Appendix
- How to request, refresh and revoke access token, please see the document "Login Kit/ Manage User Access Token".
- The process of using client_ticket. The client_ticket can help you verify whether the response can be trusted or not. Here is the main step about how to use it:
- Call GET
https://open-api.tiktok.com/v0/oauth/get_qrcode
endpoint. If the call succeed, get the "scan_qrcode_url", such as "aweme://authorize?client_key=yourclientkey&client_ticket=tobefilled&...", inside the response.
- Generate a string called client_ticket on you service, such as client_ticket="a1b2c3d4", and replace the client_ticket in "scan_qrcode_url". After replacing the client_ticket, your "scan_qrcode_url" will look like this: "aweme://authorize?client_key=yourclientkey&client_ticket=a1b2c3d4&..."
- Use the "scan_qrcode_url" to render the QR code for your users.
- Begin calling GET
https://open-api.tiktok.com/v0/oauth/check_qrcode
endpoint. After user scan the QR code, you client_ticket will be store in our service.
- While calling GET
https://open-api.tiktok.com/v0/oauth/check_qrcode
, inside response if the status is "scanned" or "confirmed", the "client_ticket" will be returned.
- Check whether the client_ticket, which is returned by GET
https://open-api.tiktok.com/v0/oauth/check_qrcode
endpoint, is same as the client_ticket you generate. If they don't match, reject this response.
- If you don't replace the client_ticket field, check_qrcode will return the default string "tobefilled" in client_ticket field.
- If you don't implement the logic for"client_ticket", this won't block you from using these two endpoints.