Build "User Search" using Neynar and OpenRanks' Global Ranking API

Surface better search results for your client.

In your client, whether it's a global user search or a search based on @mentions in a cast, both scenarios necessitate returning results that prioritize non-spam accounts at the top.

Using the combination of these APIs will lead to a latency time of around 500ms OpenRank API - 300ms and Neynar APIs - 200ms

Search functionality will be one of the pivotal features of your client. In this guide, we'll utilize Neynar's API to initially retrieve all user results based on a search query and subsequently sort these results according to the global rank of each user.

This guide expects you to have already have signed up for a Neynar account and have the basics set up ready to be able to consume Neynars' APIs. If you haven't, you can go through the getting started guide here.

Step 1: Getting the search query

This aspect is particularly tailored to your client's specifications, particularly in how it manages text inputs. For the purpose of this guide, we will utilize a static string as the search query and we also need the users FID, so we can pass it as the viewer_fid to Neynars API as a parameter in the next step, for relevant results.

// Step 1: Getting the search Query
const searchQuery = "d"
const USER_FID = 2025

Step 2: Using Neynar API to get a list of responses for the search query

In this step, we utilize Neynar's user search API endpoint to retrieve results for all users based on the username search query. The search query is set with a hardcoded limit of 10 results, which can be adjusted according to your specific requirements. Additionally, we enhance the quality of responses by passing the viewer_fid parameter as the User FID while using the Neynar API.

By the end of this step, you'll have an array of user objects that match the relevant search query.

// Step 2: Using the Neynar API to get a list of responses for the search query
const neynarBaseURL = ""
const urlSearchQueryParams = `q=${searchQuery}&viewer_fid=${USER_FID}&limit=10`
const neynarUsernameSearchURL = `${neynarBaseURL}?${urlSearchQueryParams}`
const neynarUsernameResponse = await fetch(neynarUsernameSearchURL, {
    headers: {
        'Content-Type': 'application/json',
        api_key: process.env.NEYNAR_API_KEY
const usernameResponsesArray = await neynarUsernameResponse.json().then(res => res.result.users);
// console.log(usernameResponsesArray)

Step 3: Using OpenRanks' Global Ranking APIs to sort the result based on global rank

From the previous step, we obtained an array of various users based on the search query. Now, we'll filter out FIDs for all the returned users and pass them as the body to OpenRanks Global Ranking API to obtain the global ranking for each of those users.

// Step 3: Using OpenRanks GlobalRanking APIs to find out the returned users Global Rank
// Here we use the previous Array and filter out the FIDs from it and in this step we try finding the Global Profile Rank based on engagement for each of these FIDs.
const usersGlobalRankBaseURL = ''
const usersGlobalRankResponse = await fetch(usersGlobalRankBaseURL, {
    method: 'POST',
    headers: {
        "Content-Type": "application/json"
    body: JSON.stringify( => element.fid))
const usersGlobalRankResponseArray = await usersGlobalRankResponse.json().then(element => element.result)
// console.log(usersGlobalRankResponseArray);

Step 4: Creating a new array merging the userwith rank and score key values

At the end of the previous step, we now have two arrays: one from Neynar, usernameResponsesArray, containing user objects based on the search query, and another from OpenRank, usersGlobalRankResponseArray, containing ranks of all those users' FIDs. Now, we create a new array, userResponseArrayWithRank, which merges the two based on FIDs and helps create a new array with all the user information we have from Neynar, along with each user's rank and score.

The code below accomplishes the following: it compares user FIDs from both arrays, and if the FID matches, it adds the rank and score key-value pairs from the usersGlobalRankResponse to the usernameResponsesArray.

Now, we have an array of objects for the users along with their global rank and score included.

// Step 4: Adding the rank and score key values to respective users in the userResponseArray that we got in Step 2 from Neynar
// Here we have the Global Profile Rank for each of these FIDs and then
const userResponseArrayWithRank = => {
    const correspondingUser2 = usersGlobalRankResponseArray.find(user2 => user2.fid === user1.fid);
    if (correspondingUser2) {
      user1.rank = correspondingUser2.rank;
      user1.score = correspondingUser2.score;
    return user1;
// console.log(userResponseArrayWithRank);

Step 5: Sorting the array based on global rank

In this step, we pass the previous array through the function sortByRankAscending to sort the array based on the ascending list of rankings. This ensures that highly globally ranked users appear first. This helps significantly in sorting out spam accounts, pushing them down the list rather than displaying them at the top.

function sortByRankAscending(usersArray) {
    return usersArray.sort((a, b) => a.rank - b.rank);
const sortedRankingArray = sortByRankAscending(userResponseArrayWithRank)

Future Improvements:

In the future, once personalized rankings APIs are made available for each user, which can be queried based on an input list of FIDs, providing rankings based on the viewer's FID, we can utilize this instead of the global rankings API to generate or even sort the list.

Last updated


Copyright 2024