This workflow corresponds to n8n.io template #15880 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "DG98hjxezoDCON0b",
"name": "Search Douyin users by keyword and get profile details with JustOneAPI",
"tags": [],
"nodes": [
{
"id": "9709545a-7d49-4d90-b5ef-431247c212e2",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
7408,
704
],
"parameters": {
"width": 480,
"height": 512,
"content": "## Search Douyin users by keyword and get profile details with JustOneAPI\n\n### How it works\n\n1. Trigger workflow manually to begin execution.\n2. Prepare API parameters and user inputs for Douyin search.\n3. Search Douyin users by keyword using JustOneAPI.\n4. Extract SecUID identifiers from search results.\n5. Fetch detailed profile information for each identified user.\n6. Build comprehensive user profile data structure.\n7. Output final formatted user profile information.\n\n### Setup steps\n\n- - [ ] Obtain JustOneAPI credentials and base URL\n- [ ] Configure HTTP Request nodes with proper endpoints\n- [ ] Set up Code nodes with required JavaScript logic\n\n### Customization\n\nThe workflow can be customized by modifying:\n- Search keywords in the 'Prepare API and Research Inputs' node\n- Output fields in the 'Build User Profile Details' node\n- API endpoints in the HTTP Request nodes"
},
"typeVersion": 1
},
{
"id": "29c00e84-7617-4116-a675-240e188e0eb9",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
7968,
704
],
"parameters": {
"color": 7,
"height": 96,
"content": "## Workflow Trigger\n\nManual execution point that starts the workflow"
},
"typeVersion": 1
},
{
"id": "5847c316-34cd-4839-9c55-2131c45bdc29",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
8240,
704
],
"parameters": {
"color": 7,
"height": 96,
"content": "## Input Preparation\n\nPrepares API parameters and user inputs for search"
},
"typeVersion": 1
},
{
"id": "e0061646-f026-496c-abc2-c8aeff2dc16c",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
8528,
704
],
"parameters": {
"color": 7,
"width": 528,
"height": 96,
"content": "## Search Douyin Users\n\nPerforms keyword search and handles initial results"
},
"typeVersion": 1
},
{
"id": "89db10dd-27f4-4bc9-82b3-fa8805d010c8",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
9104,
704
],
"parameters": {
"color": 7,
"width": 512,
"height": 96,
"content": "## Process Search Results\n\nExtracts identifiers from search results for further processing"
},
"typeVersion": 1
},
{
"id": "a86463c6-aa49-4f25-857b-8de9f4f9240c",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
9648,
704
],
"parameters": {
"color": 7,
"width": 256,
"height": 96,
"content": "## Fetch User Details\n\nRetrieves detailed profile information for each user"
},
"typeVersion": 1
},
{
"id": "6e3913c1-862f-4056-8079-aad1ead03c38",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
9920,
704
],
"parameters": {
"color": 7,
"width": 256,
"height": 96,
"content": "## Build User Profiles\n\nConstructs complete user profile data structure"
},
"typeVersion": 1
},
{
"id": "ce8ff220-df79-42f4-bcd3-2575ae7ae3e0",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
10240,
704
],
"parameters": {
"color": 7,
"width": 224,
"height": 96,
"content": "## Output Results\n\nFinal output of formatted user profile information"
},
"typeVersion": 1
},
{
"id": "5071c241-47f3-4b34-9083-3a83e3ad6144",
"name": "Start Workflow",
"type": "n8n-nodes-base.manualTrigger",
"position": [
8016,
832
],
"parameters": {},
"typeVersion": 1
},
{
"id": "e13824e7-b655-4d56-b6ce-be612d64c50a",
"name": "Set API and Search Parameters",
"type": "n8n-nodes-base.set",
"position": [
8288,
832
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "{\n \"baseUrl\": \"https://api.justoneapi.com\",\n \"token\": \"YOUR_JUSTONEAPI_TOKEN\",\n \"keyword\": \"YOUR_RESEARCH_KEYWORD\",\n \"page\": 1,\n \"maxUsers\": 1\n}"
},
"typeVersion": 3.4
},
{
"id": "0b9d04bf-8dc0-4abe-9252-891b8e897e2e",
"name": "Search Douyin Users by Keyword",
"type": "n8n-nodes-base.httpRequest",
"position": [
8576,
832
],
"parameters": {
"url": "={{$json.baseUrl + '/api/douyin/search-user/v2'}}",
"options": {
"redirect": {
"redirect": {}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "token",
"value": "={{$json.token}}"
},
{
"name": "keyword",
"value": "={{$json.keyword}}"
},
{
"name": "page",
"value": "={{$json.page}}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "2ee82d69-c7ab-404f-b085-608e374eff06",
"name": "Output Search Results",
"type": "n8n-nodes-base.set",
"position": [
8912,
1056
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={{$json}}"
},
"typeVersion": 3.4
},
{
"id": "942d569b-a747-4b91-8d91-12f6ecf93bba",
"name": "Extract SecUIDs from Results",
"type": "n8n-nodes-base.code",
"position": [
9152,
832
],
"parameters": {
"jsCode": "const cfg = $('Set API and Search Parameters').first().json;\nconst maxUsers = Math.max(1, Number(cfg.maxUsers || 1));\nconst token = cfg.token;\nconst baseUrl = cfg.baseUrl;\nconst keyword = cfg.keyword;\nconst page = cfg.page;\n\n// Parser adjusted from the real Douyin search-user/v2 response.\n// Real path used here:\n// response[0].data.business_data[].data.raw_data -> JSON string -> user_info\n// The node keeps raw search data and emits the first unique sec_uid by default.\n\nconst rows = $input.all();\n\nfunction asArray(value) {\n return Array.isArray(value) ? value : [value];\n}\n\nfunction parseRawData(rawData) {\n if (typeof rawData !== 'string' || rawData.length === 0) return {};\n try {\n return JSON.parse(rawData);\n } catch (error) {\n return { parseError: error.message, rawData };\n }\n}\n\nfunction firstUrl(imageObject) {\n const list = imageObject?.url_list;\n return Array.isArray(list) && list.length > 0 ? list[0] : '';\n}\n\nconst candidates = [];\n\nfor (const row of rows) {\n for (const responseItem of asArray(row.json)) {\n const data = responseItem?.data || {};\n const businessData = Array.isArray(data.business_data) ? data.business_data : [];\n\n for (const item of businessData) {\n const itemData = item?.data || {};\n const parsedRawData = parseRawData(itemData.raw_data);\n const userInfo = parsedRawData.user_info || {};\n const secUid = userInfo.sec_uid;\n\n if (typeof secUid !== 'string' || secUid.length === 0) continue;\n\n candidates.push({\n secUid,\n uid: userInfo.uid || '',\n nickname: userInfo.nickname || '',\n gender: userInfo.gender ?? null,\n uniqueId: userInfo.unique_id || '',\n followerCount: userInfo.follower_count ?? null,\n followerCountText: Array.isArray(userInfo.display_info)\n ? (userInfo.display_info.find(info => typeof info?.text === 'string' && info.text.includes('\u7c89\u4e1d'))?.text || '')\n : '',\n douyinIdText: userInfo.versatile_display || '',\n verificationType: userInfo.verification_type ?? null,\n customVerify: userInfo.custom_verify || '',\n enterpriseVerifyReason: userInfo.enterprise_verify_reason || '',\n liveStatus: userInfo.live_status ?? null,\n roomId: userInfo.room_id ?? null,\n avatarThumb: firstUrl(userInfo.avatar_thumb),\n avatarMedium: firstUrl(userInfo.avatar_medium),\n avatarLarger: firstUrl(userInfo.avatar_larger),\n searchResultId: parsedRawData.dcm_info?.dcm_extra?.search_result_id || itemData.provider_doc_id_str || '',\n searchId: parsedRawData.dcm_info?.dcm_extra?.search_id || data.business_config?.next_page?.search_id || data.log?.search_id || '',\n dataId: item.data_id || '',\n cardId: item.card_id || itemData.card_id || '',\n cardTypeName: itemData.card_type_name || '',\n rawUserInfo: userInfo,\n rawSearchCard: item\n });\n }\n }\n}\n\nconst seen = new Set();\nconst selected = [];\nfor (const user of candidates) {\n if (seen.has(user.secUid)) continue;\n seen.add(user.secUid);\n selected.push(user);\n if (selected.length >= maxUsers) break;\n}\n\nreturn selected.map((user, index) => ({\n json: {\n baseUrl,\n token,\n keyword,\n page,\n secUid: user.secUid,\n userRank: index + 1,\n selectedBy: 'search-user-v2-business-data-raw-data-user-info',\n searchUser: user,\n rawSearchOutput: rows.map(row => row.json)\n }\n}));"
},
"typeVersion": 2
},
{
"id": "4edd8e85-b15c-4f42-8821-e750ab32796d",
"name": "Output Extracted SecUIDs",
"type": "n8n-nodes-base.set",
"position": [
9472,
1056
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={{$json}}"
},
"typeVersion": 3.4
},
{
"id": "e38c94a8-093b-426e-b57a-cf17f9054a05",
"name": "Fetch User Details from Douyin",
"type": "n8n-nodes-base.httpRequest",
"position": [
9696,
832
],
"parameters": {
"url": "={{$json.baseUrl + '/api/douyin/get-user-detail/v3'}}",
"options": {
"redirect": {
"redirect": {}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "token",
"value": "={{$json.token}}"
},
{
"name": "secUid",
"value": "={{$json.secUid}}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "9c4fdbce-a805-4a24-a575-db936cf033ff",
"name": "Build User Profile Data",
"type": "n8n-nodes-base.code",
"position": [
9968,
832
],
"parameters": {
"jsCode": "const rows = $input.all();\nconst cfg = $('Set API and Search Parameters').first().json;\nlet extractedUsers = [];\ntry {\n extractedUsers = $('Extract SecUIDs from Results').all().map(item => item.json);\n} catch (error) {\n extractedUsers = [];\n}\n\nfunction firstUrl(imageObject) {\n const list = imageObject?.url_list;\n return Array.isArray(list) && list.length > 0 ? list[0] : '';\n}\n\nfunction firstCoverUrl(coverList) {\n if (!Array.isArray(coverList) || coverList.length === 0) return '';\n return firstUrl(coverList[0]);\n}\n\nfunction firstProfileCoverUrl(profileCoverList) {\n if (!Array.isArray(profileCoverList) || profileCoverList.length === 0) return '';\n return firstUrl(profileCoverList[0]?.cover_url);\n}\n\nfunction getDetailUser(root) {\n // Real get-user-detail/v3 response path from test output:\n // response[0].data.user\n const data = root?.data || {};\n return data.user || {};\n}\n\nreturn rows.map((item, index) => {\n const detailRoot = item.json || {};\n const extracted = extractedUsers[index] || {};\n const searchUser = extracted.searchUser || {};\n const user = getDetailUser(detailRoot);\n\n const avatarUrls = {\n avatarThumb: firstUrl(user.avatar_thumb),\n avatarMedium: firstUrl(user.avatar_medium),\n avatarLarger: firstUrl(user.avatar_larger),\n avatar168x168: firstUrl(user.avatar_168x168),\n avatar300x300: firstUrl(user.avatar_300x300)\n };\n\n const coverUrls = {\n coverImage: firstCoverUrl(user.cover_url),\n whiteCoverImage: firstCoverUrl(user.white_cover_url),\n profileCoverImage: firstProfileCoverUrl(user.cover_and_head_image_info?.profile_cover_list)\n };\n\n const shareInfo = user.share_info || {};\n\n return {\n json: {\n requestedKeyword: cfg.keyword || '',\n userRank: extracted.userRank || index + 1,\n selectedBy: extracted.selectedBy || 'search-user-v2-business-data-raw-data-user-info',\n\n secUid: user.sec_uid || '',\n uid: user.uid || '',\n nickname: user.nickname || '',\n uniqueId: user.unique_id || '',\n shortId: user.short_id || '',\n signature: user.signature || '',\n signatureLanguage: user.signature_language || '',\n ipLocation: user.ip_location || '',\n gender: user.gender ?? null,\n\n followerCount: user.follower_count ?? null,\n followingCount: user.following_count ?? null,\n awemeCount: user.aweme_count ?? null,\n favoritingCount: user.favoriting_count ?? null,\n totalFavorited: user.total_favorited ?? null,\n mplatformFollowersCount: user.mplatform_followers_count ?? null,\n maxFollowerCount: user.max_follower_count ?? null,\n\n verificationType: user.verification_type ?? null,\n customVerify: user.custom_verify || '',\n enterpriseVerifyReason: user.enterprise_verify_reason || '',\n accountCertInfo: user.account_cert_info || '',\n roleId: user.role_id || '',\n\n liveStatus: user.live_status ?? null,\n roomId: user.room_id ?? null,\n roomIdStr: user.room_id_str || '',\n secret: user.secret ?? null,\n isStar: user.is_star ?? null,\n isBan: user.is_ban ?? null,\n isBlock: user.is_block ?? null,\n isBlocked: user.is_blocked ?? null,\n\n country: user.country || '',\n province: user.province || '',\n city: user.city || '',\n district: user.district || '',\n location: user.location || '',\n storeRegion: user.store_region || '',\n\n hasCommerceEntry: user.commerce_user_info?.has_ads_entry ?? null,\n showStarAtlasCooperation: user.commerce_user_info?.show_star_atlas_cooperation ?? null,\n starAtlas: user.commerce_user_info?.star_atlas ?? null,\n commerceUserLevel: user.commerce_user_level ?? null,\n withCommerceEntry: user.with_commerce_entry ?? null,\n withNewGoods: user.with_new_goods ?? null,\n\n avatarUrls,\n coverUrls,\n shareInfo: {\n shareTitle: shareInfo.share_title || '',\n shareDesc: shareInfo.share_desc || '',\n shareUrl: shareInfo.share_url || '',\n shareWeiboDesc: shareInfo.share_weibo_desc || '',\n shareQrcodeUrl: firstUrl(shareInfo.share_qrcode_url)\n },\n\n auxiliaryOutput: {\n statusCode: detailRoot.data?.status_code ?? null,\n statusMsg: detailRoot.data?.status_msg ?? null,\n logId: detailRoot.data?.extra?.logid || '',\n imprId: detailRoot.data?.log_pb?.impr_id || '',\n followersDetail: user.followers_detail || [],\n personalTagList: user.personal_tag_list || [],\n profileTabInfo: user.profile_tab_info || {},\n commerceInfo: user.commerce_info || {},\n commerceUserInfo: user.commerce_user_info || {},\n generalPermission: user.general_permission || {},\n userPermissions: user.user_permissions || [],\n profileComponentDisabled: user.profile_component_disabled || [],\n selectedSearchUser: searchUser\n },\n\n rawSearchOutput: extracted.rawSearchOutput || [],\n rawUserDetailOutput: detailRoot\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "e1bb896f-8bdb-4de8-a7a4-90addca754c0",
"name": "Output Final User Profiles",
"type": "n8n-nodes-base.set",
"position": [
10288,
832
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={{$json}}"
},
"typeVersion": 3.4
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "791e1222-7905-4c8f-822b-d7b3802abedc",
"connections": {
"Start Workflow": {
"main": [
[
{
"node": "Set API and Search Parameters",
"type": "main",
"index": 0
}
]
]
},
"Build User Profile Data": {
"main": [
[
{
"node": "Output Final User Profiles",
"type": "main",
"index": 0
}
]
]
},
"Extract SecUIDs from Results": {
"main": [
[
{
"node": "Output Extracted SecUIDs",
"type": "main",
"index": 0
},
{
"node": "Fetch User Details from Douyin",
"type": "main",
"index": 0
}
]
]
},
"Set API and Search Parameters": {
"main": [
[
{
"node": "Search Douyin Users by Keyword",
"type": "main",
"index": 0
}
]
]
},
"Fetch User Details from Douyin": {
"main": [
[
{
"node": "Build User Profile Data",
"type": "main",
"index": 0
}
]
]
},
"Search Douyin Users by Keyword": {
"main": [
[
{
"node": "Output Search Results",
"type": "main",
"index": 0
},
{
"node": "Extract SecUIDs from Results",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Use this n8n workflow to search Douyin users from a keyword and get profile details with JustOneAPI.
Source: https://n8n.io/workflows/15880/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow allows you to import any workflow from a file or another n8n instance and map the credentials easily. A multi-form setup guides you through the entire process At the beginning you have t
[n8n] Advanced URL Parsing and Shortening Workflow - Switchy.io Integration. Uses splitInBatches, stickyNote, httpRequest, html. Event-driven trigger; 56 nodes.
[](https://youtu.be/c7yCZhmMjtI)
This automation organizes your n8n workflows files into categorizes (Active, Template, Done, Archived) and uploads them directly to a categorized Google Drive folders. It is designed to help users man
Create Animated Stories using GPT-4o-mini, Midjourney, Kling and Creatomate API. Uses httpRequest. Event-driven trigger; 51 nodes.