Search Profiles
Search and filter wallet profiles by address, socials, labels, net worth, chain activity, and more. Returns paginated results with full profile data.
Authentication
This endpoint requires authentication using a Workspace API Key withprofiles:read permission. Include the API key in your request headers:
Query Parameters
address
Filter by a specific wallet address (exact match). Accepts an EVM address, a Solana address, or an ENS name (e.g. vitalik.eth) which is resolved to an address before filtering. An unresolvable ENS name or an otherwise invalid value returns a 400 BAD_REQUEST.
search
Case-insensitive free-text search across wallet addresses and all supported social fields. This includes values from both global wallet profiles and project-scoped identify overrides.
expand
Comma-separated list of optional sections to include in each profile response.
Supported values:
apps- DeFi app interactions and balanceschains- Per-chain activity metricstokens- Token holdingslabels- Wallet labels
chains, tokens, or apps increases response size and latency. The collections are capped at 50 items each.order_by
Field to sort results by. Supported values:
last_onchain(default) - Last on-chain activity timestampfirst_onchain- First on-chain activity timestampnet_worth_usd- Total net worthupdated_at- Last profile update timestamptx_count- Total transaction countfirst_seen- First seen timestamp in your applast_seen- Last seen timestamp in your appnum_sessions- Number of sessionsrevenue- Total revenuevolume- Total volumepoints- Total points
order_dir
Sort direction:
desc(default) - Descending orderasc- Ascending order
page
1-indexed page number to return.
- Default:
1
size
Page size - number of profiles per page.
- Default:
100 - Maximum:
1000
Request Body (Filters)
The search endpoint supports rich filtering capabilities through a JSON request body. The body contains a filter object withconditions and logic.
Filter Schema
| Field | Type | Description |
|---|---|---|
conditions | array | Array of filter conditions |
logic | string | How to combine conditions: and (all must match) or or (any must match). Default: and |
Filter Condition
Each condition in theconditions array has:
| Field | Type | Description |
|---|---|---|
field | string | The field path to filter on (see Field Reference below) |
op | string | The comparison operator |
value | string | number | boolean | array | The value to compare against |
scope | string | (Optional) Only for token filters: any (wallet + protocols) or protocol (specific protocol only) |
appId | string | (Optional) Only for token filters with scope: "protocol". The DeFi protocol ID (e.g., aave-v3, compound-v3) |
Operators
| Operator | Description | Example |
|---|---|---|
eq | Equals | {"field": "users.device", "op": "eq", "value": "Desktop"} |
neq | Not equals | {"field": "users.os", "op": "neq", "value": "Windows"} |
gt | Greater than | {"field": "users.net_worth_usd", "op": "gt", "value": 1000} |
gte | Greater than or equal | {"field": "users.volume", "op": "gte", "value": 100} |
lt | Less than | {"field": "users.net_worth_usd", "op": "lt", "value": 50000} |
lte | Less than or equal | {"field": "chains.1.balance", "op": "lte", "value": 10000} |
in | In array | {"field": "users.lifecycle", "op": "in", "value": ["New", "Power user"]} |
nin | Not in array | {"field": "users.location", "op": "nin", "value": ["US", "UK"]} |
contains | Case-insensitive substring match for social fields only | {"field": "users.twitter", "op": "contains", "value": "vitalik"} |
Field Reference
User Fields (users.*)
Filter by user engagement and profile data. Use the format users.{attribute}.
Profile Fields
| Field | Type | Description |
|---|---|---|
users.net_worth_usd | number | Total net worth in USD |
users.volume | number | Total trading volume |
users.revenue | number | Total revenue |
users.points | number | Total points |
Engagement Fields
| Field | Type | Description |
|---|---|---|
users.device | string | Device type (e.g., Desktop, Mobile) |
users.browser | string | Browser name (e.g., Chrome, Safari) |
users.os | string | Operating system (e.g., macOS, Windows) |
users.location | string | Country code (e.g., US, NG) |
UTM & Referral Fields
| Field | Type | Description |
|---|---|---|
users.first_utm_source | string | First UTM source |
users.last_utm_source | string | Last UTM source |
users.first_utm_medium | string | First UTM medium |
users.last_utm_medium | string | Last UTM medium |
users.first_utm_campaign | string | First UTM campaign |
users.last_utm_campaign | string | Last UTM campaign |
users.first_utm_content | string | First UTM content |
users.last_utm_content | string | Last UTM content |
users.first_utm_term | string | First UTM term |
users.last_utm_term | string | Last UTM term |
users.first_referrer | string | First referrer domain |
users.last_referrer | string | Last referrer domain |
users.first_referrer_url | string | First referrer full URL |
users.last_referrer_url | string | Last referrer full URL |
users.first_ref | string | First referral code |
users.last_ref | string | Last referral code |
Lifecycle Filter
Filter by user lifecycle stage. Valid values:At Risk, Churned, New, Power user, Resurrected, Returning.
| Field | Type | Description |
|---|---|---|
users.lifecycle | string | User lifecycle stage |
Social Fields
Social fields support two modes:- Presence checks: use an empty string value to match profiles where the field is present.
- Value matching: use
eq,neq, orcontainswith a non-empty string to match the actual social value.
| Field | Description |
|---|---|
users.ens | ENS name |
users.farcaster | Farcaster username |
users.lens | Lens handle |
users.basenames | Base names |
users.linea | Linea identifier |
users.discord | Discord username |
users.telegram | Telegram username |
users.website | Website URL |
users.twitter | Twitter/X handle |
users.github | GitHub username |
users.linkedin | LinkedIn profile |
users.email | Email address |
users.instagram | Instagram handle |
users.facebook | Facebook profile |
users.tiktok | TikTok handle |
users.youtube | YouTube channel or handle |
users.reddit | Reddit username |
bob:
Chain Filters (chains.*)
Filter by per-chain net worth. Supports filtering across all chains or specific chains.
All Chains
Usechains.balance to filter across all chains (returns profiles where any chain matches).
Example - Find users with >$1,000 on any chain:
Specific Chain
Usechains.{chain_id}.balance to filter on a specific chain.
Common chain IDs:
1- Ethereum Mainnet137- Polygon42161- Arbitrum One10- Optimism8453- Base56- BNB Chain43114- Avalanche
App Filters (apps.*)
Filter by DeFi app interactions and balances.
All Chains
Useapps.{app_id}.balance to filter by app balance across all chains.
Example - Find users with >$1,000 in Uniswap:
Specific Chain
Useapps.{chain_id}.{app_id}.balance to filter by app balance on a specific chain.
Example - Find users with >$500 in Aave on Ethereum:
Token Filters (tokens.*)
Filter by token holdings. Supports optional scope and appId parameters.
Token Filter Parameters
| Parameter | Type | Description |
|---|---|---|
scope | string | any (default) = wallet + all protocols, protocol = specific protocol only |
appId | string | Only for scope: "protocol". Specifies the DeFi protocol ID (e.g., aave-v3, compound-v3, uniswap-v3) |
All Chains
Usetokens.{token_address}.balance to filter by token balance across all chains.
Example - Find users holding >1000 USDC (any chain):
Specific Chain
Usetokens.{chain_id}.{token_address}.balance to filter by token balance on a specific chain.
Example - Find users with >500 USDC on Ethereum:
Protocol-Specific Token Filters
Usescope: "protocol" with appId to filter for tokens deposited in a specific DeFi protocol.
Example - Find users with USDC deposited in any protocol:
Label Filters (labels.*)
Filter by wallet labels. Use the format labels.{tag_id}.
Common label IDs:
coinbase.verified_account- Coinbase verified account (boolean)coinbase.verified_country- Coinbase verified country codecoinbase.verified_coinbase_one- Coinbase One membership (boolean)sanctions.designated- Sanctioned address (boolean)passport.models_aggregate_score- Passport aggregate score (0-100)passport.unique_humanity_score- Passport uniqueness score
Combined Filter Examples
High-Value Web3 Users
Find users with >$10,000 net worth, ENS name, and activity on Ethereum:Active DeFi Users
Find users with activity in Uniswap or Aave:Verified Power Users
Find Coinbase-verified power users from specific countries:Multi-Chain Whales
Find users with significant holdings across multiple chains:Response
The response is a paginated envelope of wallet profiles.Response Fields
| Field | Type | Description |
|---|---|---|
data | array | Array of wallet profiles matching the search criteria |
total | integer | Total number of profiles matching the criteria across all pages |
page | integer | 1-indexed page number echoed from the request |
size | integer | Page size echoed from the request |
has_more | boolean | true if there are pages after the current one |
Profile Fields
Each profile in thedata array includes:
| Field | Type | Description |
|---|---|---|
address | string | Wallet address |
net_worth_usd | number | Total net worth in USD |
tx_count | integer | Total transaction count |
first_onchain | string | First on-chain activity timestamp (ISO 8601) |
last_onchain | string | Last on-chain activity timestamp (ISO 8601) |
lifecycle | string | User lifecycle stage: At Risk, Churned, New, Power user, Resurrected, Returning |
ens | string | null | ENS name |
farcaster | string | null | Farcaster username |
twitter | string | null | Twitter/X handle |
discord | string | null | Discord username |
telegram | string | null | Telegram username |
email | string | null | Email address |
first_seen | string | null | First seen timestamp in your app |
last_seen | string | null | Last seen timestamp in your app |
num_sessions | integer | null | Total number of sessions |
revenue | number | null | Total revenue |
volume | number | null | Total volume |
points | number | null | Total points |
chains | array | null | Per-chain data (when expanded) |
apps | array | null | DeFi app data (when expanded) |
tokens | array | null | Token holdings (when expanded) |
labels | array | null | Wallet labels (when expanded) |
Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Invalid query parameters or malformed JSON in request body |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | FORBIDDEN | API key does not have profiles:read permission |
| 500 | INTERNAL_SERVER_ERROR | Failed to fetch wallet profile data |
Authorizations
Workspace API key (e.g. formo_xxx). Create one in the Formo dashboard under Team Settings > API Keys.
Query Parameters
Filter by wallet address. Accepts an EVM (0x...) or Solana address, or an ENS name (e.g. vitalik.eth) which is resolved to an address.
Comma-separated: apps, chains, tokens, labels
Sort field
net_worth_usd, tx_count, first_onchain, last_onchain, updated_at, first_seen, last_seen, num_sessions, revenue, volume, points Sort direction
asc, desc 1-indexed page number (default 1).
x >= 1Page size (default 100, max 1000).
1 <= x <= 1000Body
Optional filter conditions
Response
Paginated wallet profile search results.
Pagination cursor returned alongside data on every paginated list endpoint. Use these to walk pages: has_more is true while page * size < total. Combine with the matching Page and Size query parameters to request the next page.