{
  "id": "5fiDrb0Na7EFNOu1",
  "name": "Research Xiaohongshu note details from a keyword with JustOneAPI",
  "tags": [],
  "nodes": [
    {
      "id": "f722e5c4-9937-4708-a0b9-2bd99e141493",
      "name": "Template Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1424,
        1200
      ],
      "parameters": {
        "width": 500,
        "height": 792,
        "content": "## Get Xiaohongshu note details from a keyword with JustOneAPI\n\nUse this workflow to turn one Xiaohongshu keyword into a structured note detail result.\n\n## Who\u2019s it for\n\nThis template is for content researchers, creator operations teams, marketing teams, and automation builders who want to collect Xiaohongshu note details inside n8n.\n\n## What this workflow does\n\nThe workflow searches Xiaohongshu notes with the V2 search endpoint, extracts unique note IDs from the returned results, keeps the first unique note ID by default, fetches note details, and returns a structured output for downstream use.\n\n## How to set up\n\n1. Open **Prepare API and Research Inputs**\n2. Add your JustOneAPI token\n3. Update `keyword`\n4. Optionally adjust `page`, `sortSearchNoteV2`, `noteType`, `noteTime`, and `maxNotes`\n5. Leave `maxNotes` at `1` if you want to fetch only the first unique result by default\n6. Run the workflow and review the final output node\n\n## Requirements\n\n- A JustOneAPI token\n- An n8n environment with HTTP Request support\n\n## How to customize the workflow\n\n- Increase `maxNotes` to fetch more note details\n- Change `noteTime` for a different search time range\n- Send the final output to Sheets, Airtable, Notion, a database, or an AI step"
      },
      "typeVersion": 1
    },
    {
      "id": "4a152ab4-3d22-45ee-b589-9c7596abe05e",
      "name": "Step 1 - Start Workflow",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1984,
        1344
      ],
      "parameters": {
        "color": 7,
        "height": 192,
        "content": "## Start the workflow\n\nThis workflow is started manually.\n\nUse this trigger when you want to run one keyword-based Xiaohongshu note research job on demand."
      },
      "typeVersion": 1
    },
    {
      "id": "e8a9a0af-c429-439d-a920-c42818f30ad1",
      "name": "Step 2 - Configure Inputs",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2256,
        1232
      ],
      "parameters": {
        "color": 7,
        "width": 224,
        "height": 480,
        "content": "## Configure API and research inputs\n\nThis group defines the shared values used across the workflow.\n\nRequired:\n- `token`\n- `keyword`\n\nOptional:\n- `page`\n- `sortSearchNoteV2`\n- `noteType`\n- `noteTime`\n- `maxNotes`\n\nRecommended defaults:\n- `noteTime = \u4e00\u5929\u5185`\n- `maxNotes = 1`"
      },
      "typeVersion": 1
    },
    {
      "id": "87b1f9b6-efbe-4fd3-ad16-e59dca12ae50",
      "name": "Step 3 - Search Notes",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2528,
        1360
      ],
      "parameters": {
        "color": 7,
        "width": 528,
        "height": 224,
        "content": "## Search Xiaohongshu notes by keyword\n\nThis group sends the keyword search request to the Xiaohongshu V2 search endpoint.\n\nUse this step to:\n- search notes from one keyword\n- inspect the raw search response\n- confirm that note IDs are returned before moving to the next step"
      },
      "typeVersion": 1
    },
    {
      "id": "8af7cf52-0791-4bae-b8ae-8a15600e7478",
      "name": "Step 4 - Extract Note IDs",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3216,
        1360
      ],
      "parameters": {
        "color": 7,
        "width": 512,
        "height": 232,
        "content": "## Extract and limit note IDs\n\nThis group reads `data.items[].note.id` from the search response.\n\nIt then:\n- removes duplicate note IDs\n- keeps the first unique note ID by default\n- passes the selected IDs into the detail request step\n\nIncrease `maxNotes` if you want to fetch details for more than one result."
      },
      "typeVersion": 1
    },
    {
      "id": "d307a53a-a76a-4496-9651-591a38b0eac7",
      "name": "Step 5 - Fetch Note Details",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3760,
        1360
      ],
      "parameters": {
        "color": 7,
        "height": 240,
        "content": "## Fetch note details\n\nThis group requests the Xiaohongshu note detail endpoint once for each selected note ID.\n\nUse this step to retrieve the raw detail response before it is transformed into the final output structure."
      },
      "typeVersion": 1
    },
    {
      "id": "e0d23d75-5fc0-4240-b3b6-d904f39d43aa",
      "name": "Step 6 - Build Final Output",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4032,
        1344
      ],
      "parameters": {
        "color": 7,
        "width": 528,
        "height": 340,
        "content": "## Build the final note detail output\n\nThis group converts the raw detail response into a cleaner result with fields such as:\n- `noteId`\n- `title`\n- `desc`\n- `authorName`\n- `likeCount`\n- `commentCount`\n- `shareCount`\n- `collectedCount`\n- `noteUrl`\n\nUse the final output node as the handoff point for reporting, storage, alerts, or AI analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "408f485d-04e8-4229-80bb-05b91f6481da",
      "name": "Manual Execution Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        2016,
        1728
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "79b2f52c-22fa-4ca1-bfb8-d2c1f33d4aaa",
      "name": "Prepare API and Research Inputs",
      "type": "n8n-nodes-base.set",
      "position": [
        2288,
        1728
      ],
      "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  \"sortSearchNoteV2\": \"general\",\n  \"noteType\": \"_0\",\n  \"noteTime\": \"\u4e00\u5929\u5185\",\n  \"maxNotes\": 1\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "f2ec2e16-ecb6-4226-ba01-f65b6f7824e1",
      "name": "Fetch Xiaohongshu Notes by Keyword",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2576,
        1728
      ],
      "parameters": {
        "url": "={{$json.baseUrl + '/api/xiaohongshu/search-note/v2'}}",
        "options": {
          "redirect": {
            "redirect": {}
          }
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "token",
              "value": "={{$json.token}}"
            },
            {
              "name": "keyword",
              "value": "={{$json.keyword}}"
            },
            {
              "name": "page",
              "value": "={{$json.page}}"
            },
            {
              "name": "sort",
              "value": "={{$json.sortSearchNoteV2}}"
            },
            {
              "name": "noteType",
              "value": "={{$json.noteType}}"
            },
            {
              "name": "noteTime",
              "value": "={{$json.noteTime}}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d0a7b714-5939-427e-bb3c-289f3c67b3d8",
      "name": "Output Search Results Data",
      "type": "n8n-nodes-base.set",
      "position": [
        2912,
        1952
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{$json}}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "1a5721c0-f95d-4eba-8970-c6df02b0b4dd",
      "name": "Extract Note IDs from Results",
      "type": "n8n-nodes-base.code",
      "position": [
        3264,
        1728
      ],
      "parameters": {
        "jsCode": "const cfg = $('Prepare API and Research Inputs').first().json;\nconst maxNotes = Math.max(1, Number(cfg.maxNotes || 1));\nconst token = cfg.token;\nconst baseUrl = cfg.baseUrl;\nconst keyword = cfg.keyword;\n\n// Match the real search-note/v2 response structure:\n// [\n//   {\n//     code: 0,\n//     data: {\n//       items: [\n//         { model_type: \\\"note\\\", note: { id: \\\"...\\\" } }\n//       ]\n//     }\n//   }\n// ]\n\nconst rows = $input.all();\nconst ids = [];\n\nfor (const row of rows) {\n  const items = row.json?.data?.items || [];\n  for (const entry of items) {\n    const noteId = entry?.note?.id;\n    if (typeof noteId === 'string' && noteId.length >= 8) {\n      ids.push(noteId);\n    }\n  }\n}\n\nconst uniqueIds = [...new Set(ids)].slice(0, maxNotes);\n\nreturn uniqueIds.map((noteId, index) => ({\n  json: {\n    baseUrl,\n    token,\n    keyword,\n    noteId,\n    noteRank: index + 1,\n    selectedBy: 'search-note-v2'\n  }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "11d227f5-6444-4466-9f8d-8d6ebc0a4dc5",
      "name": "Output Extracted Note IDs",
      "type": "n8n-nodes-base.set",
      "position": [
        3584,
        1952
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{$json}}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "f17563ca-a974-4121-bff2-00b1db56751e",
      "name": "Fetch Xiaohongshu Note Details",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3808,
        1728
      ],
      "parameters": {
        "url": "={{$json.baseUrl + '/api/xiaohongshu/get-note-detail/v1'}}",
        "options": {
          "redirect": {
            "redirect": {}
          }
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "token",
              "value": "={{$json.token}}"
            },
            {
              "name": "noteId",
              "value": "={{$json.noteId}}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "1ed6d5f9-64ab-4b72-bb5e-ab7a5c250dfe",
      "name": "Build Note Details List",
      "type": "n8n-nodes-base.code",
      "position": [
        4080,
        1728
      ],
      "parameters": {
        "jsCode": "const rows = $input.all();\n\nreturn rows.map(item => {\n  const root = item.json || {};\n  const detailRoot = Array.isArray(root.data) && root.data.length > 0 ? root.data[0] : {};\n  const note = Array.isArray(detailRoot.note_list) && detailRoot.note_list.length > 0 ? detailRoot.note_list[0] : {};\n  const user = note.user || detailRoot.user || {};\n  const shareInfo = note.share_info || {};\n  const qqMiniProgramInfo = note.qq_mini_program_info || {};\n  const miniProgramInfo = note.mini_program_info || {};\n\n  return {\n    json: {\n      noteId: note.id || '',\n      title: note.title || note.desc || '',\n      desc: note.desc || '',\n      authorName: user.nickname || user.name || '',\n      authorId: user.userid || user.id || '',\n      likeCount: note.liked_count ?? 0,\n      commentCount: note.comments_count ?? 0,\n      shareCount: note.shared_count ?? 0,\n      collectedCount: note.collected_count ?? 0,\n      noteType: note.type || '',\n      noteUrl: shareInfo.link || qqMiniProgramInfo.webpage_url || miniProgramInfo.webpage_url || '',\n      ipLocation: note.ip_location || '',\n      requestedKeyword: $('Prepare API and Research Inputs').first().json.keyword || '',\n      raw: root\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "76632de5-63c5-48e2-80ca-8e102cd831a7",
      "name": "Output Final Note Details",
      "type": "n8n-nodes-base.set",
      "position": [
        4560,
        1728
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{$json}}"
      },
      "typeVersion": 3.4
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "6788f8e4-df36-4549-b509-e45740fdf85f",
  "connections": {
    "Build Note Details List": {
      "main": [
        [
          {
            "node": "Output Final Note Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Execution Trigger": {
      "main": [
        [
          {
            "node": "Prepare API and Research Inputs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Note IDs from Results": {
      "main": [
        [
          {
            "node": "Output Extracted Note IDs",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Xiaohongshu Note Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Xiaohongshu Note Details": {
      "main": [
        [
          {
            "node": "Build Note Details List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare API and Research Inputs": {
      "main": [
        [
          {
            "node": "Fetch Xiaohongshu Notes by Keyword",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Xiaohongshu Notes by Keyword": {
      "main": [
        [
          {
            "node": "Output Search Results Data",
            "type": "main",
            "index": 0
          },
          {
            "node": "Extract Note IDs from Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}