The formo profiles command group lets you look up individual wallet profiles, search across your entire user base with filters and sorting, merge-update identity properties, and manage labels on a wallet.
Fetch a single wallet profile by address or ENS name.
Requires profiles:read scope on your API key.
Arguments
| Argument | Type | Required | Description |
|---|
address | string | ✅ | Wallet address (0x…) or ENS name |
Options
| Option | Type | Required | Description |
|---|
--expand | string | ❌ | Comma-separated list of fields to expand: apps, chains, tokens, labels |
Examples
# Get a wallet profile by address
formo profiles get 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
# Get a profile by ENS name
formo profiles get vitalik.eth
# Get profile with expanded labels and chains
formo profiles get vitalik.eth --expand labels,chains
# Get profile with all expanded fields
formo profiles get 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --expand apps,chains,tokens,labels
Expand fields
| Field | Description |
|---|
apps | DApps the wallet has interacted with |
chains | Blockchain networks the wallet is active on |
tokens | Token holdings for the wallet |
labels | Wallet labels and tags |
Search wallet profiles with optional filters, sorting, and pagination.
Requires profiles:read scope on your API key.
Options
| Option | Type | Required | Description |
|---|
--address | string | ❌ | Filter by wallet address |
--page | number | ❌ | Page number (1-indexed, default 1) |
--size | number | ❌ | Page size (default 100, max 1000) |
--order-by | enum | ❌ | Field to sort by (see values below) |
--order-dir | enum | ❌ | Sort direction: asc or desc |
--expand | string | ❌ | Comma-separated fields to expand |
--conditions | string | ❌ | JSON array of FilterCondition objects for advanced filtering |
--logic | enum | ❌ | Logic operator for combining conditions: and (default) or or |
--order-by values
| Value | Description |
|---|
last_onchain | Last on-chain activity timestamp |
first_onchain | First on-chain activity timestamp |
net_worth_usd | Total net worth in USD |
updated_at | Profile last updated |
tx_count | Total transaction count |
first_seen | First seen by Formo |
last_seen | Last seen by Formo |
num_sessions | Number of sessions |
revenue | Revenue attributed |
volume | Volume attributed |
points | Points attributed |
Examples
# List first 10 profiles
formo profiles search --size 10
# Top 5 profiles by net worth
formo profiles search --order-by net_worth_usd --order-dir desc --size 5
# Get the second page of 20 profiles
formo profiles search --page 2 --size 20
# Search with a filter condition
formo profiles search \
--conditions '[{"field":"users.net_worth_usd","op":"gt","value":10000}]' \
--size 20
# Search profiles matching either condition (OR logic)
formo profiles search \
--conditions '[{"field":"users.net_worth_usd","op":"gt","value":10000},{"field":"users.volume","op":"gt","value":1000}]' \
--logic or \
--size 20
# Filter by on-chain balance on a specific chain (Ethereum = chain 1)
formo profiles search \
--conditions '[{"field":"chains.1.balance","op":"gt","value":1000}]' \
--size 20
The response is a paginated envelope: { data, total, page, size, has_more }. Use has_more to know whether to fetch --page <n+1>.
FilterCondition reference
The --conditions option accepts a JSON array of filter condition objects:
[
{ "field": "users.net_worth_usd", "op": "gt", "value": 10000 },
{ "field": "chains.1.balance", "op": "gte", "value": 1000 }
]
field must be a typed path (prefixed by its category; see the table
below). The CLI rejects a bare/untyped field (e.g. net_worth_usd) with an
error, because the API would otherwise silently ignore it: no error, no
filtering, returning the entire unfiltered dataset. Always prefix the field,
e.g. users.net_worth_usd.
| Field | Type | Description |
|---|
field | string | Typed field path (see prefixes below) |
op | string | Operator (see table below) |
value | any | Value to compare against |
scope | string | (token filters only) any or protocol |
appId | string | (token filters with scope: protocol) e.g. aave-v3 |
Field path prefixes
| Prefix | Examples |
|---|
users. | users.net_worth_usd, users.volume, users.revenue, users.points, users.device, users.location, users.lifecycle, users.ens, users.farcaster |
chains. | chains.balance (any chain), chains.1.balance (Ethereum) |
apps. | apps.uniswap-v3.balance |
tokens. | tokens.0xA0b8…48.balance |
labels. | labels.coinbase.verified_account |
Filter operators
| Operator | Description |
|---|
eq | Equal to |
neq | Not equal to |
gt | Greater than |
gte | Greater than or equal to |
lt | Less than |
lte | Less than or equal to |
in | In a set of values |
nin | Not in a set of values |
By default, multiple conditions are combined with AND logic. Use --logic or to combine with OR logic instead.
Merge-update identity properties on a wallet profile. Only the listed property keys are accepted; unknown keys are rejected server-side.
Requires profiles:write scope on your API key.
Arguments
| Argument | Type | Required | Description |
|---|
address | string | ✅ | Wallet address (0x…) or ENS name |
Options
| Option | Type | Required | Description |
|---|
--properties | string | ✅ | JSON object of properties to merge |
Allowed property keys
user_id, display_name, email, farcaster, discord, twitter, telegram, instagram, website, github, linkedin, facebook, tiktok, youtube, reddit, avatar, description, location, ens, lens, basenames, linea
Examples
# Set display name and Twitter handle
formo profiles update 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 \
--properties '{"display_name":"Vitalik","twitter":"VitalikButerin"}'
# Set just the email
formo profiles update vitalik.eth \
--properties '{"email":"alice@example.com"}'
Upsert one or more labels on a wallet profile. Provide either a single label via --tag-id or a batch via --labels.
Requires profiles:write scope on your API key.
Arguments
| Argument | Type | Required | Description |
|---|
address | string | ✅ | Wallet address (0x…) or ENS name |
Options
| Option | Type | Required | Description |
|---|
--tag-id | string | ❌ | Label identifier (e.g. vip, airdrop_eligible). Required unless --labels is provided. |
--value | string | ❌ | Optional label value (e.g. tier name, country code) |
--chain-id | string | ❌ | Optional chain identifier the label applies to |
--labels | string | ❌ | JSON array of UserLabelInput objects for batch upsert |
Examples
# Tag a wallet as VIP
formo profiles labels create 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --tag-id vip
# Apply a tiered label scoped to a chain
formo profiles labels create 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 \
--tag-id tier --value gold --chain-id 1
# Apply multiple labels in one call
formo profiles labels create 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 \
--labels '[{"tag_id":"vip"},{"tag_id":"airdrop_eligible","chain_id":"1"}]'
| Field | Type | Required | Description |
|---|
tag_id | string | ✅ | Label identifier |
value | string | ❌ | Optional label value |
chain_id | string | ❌ | Optional chain identifier |
Delete a label from a wallet profile. Pass --chain-id to scope the deletion to a chain-specific label.
Requires profiles:write scope on your API key.
Arguments
| Argument | Type | Required | Description |
|---|
address | string | ✅ | Wallet address (0x…) or ENS name |
Options
| Option | Type | Required | Description |
|---|
--tag-id | string | ✅ | Label identifier to delete |
--chain-id | string | ❌ | Optional chain identifier to scope the deletion |
Examples
# Remove the vip label
formo profiles labels delete 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --tag-id vip
# Remove a chain-scoped label
formo profiles labels delete 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 \
--tag-id tier --chain-id 1