API

Resolve

Turn a handle into an identity state: is @lyra a real Fomo identity, and can FomoPay pay it on Robinhood Chain right now? Resolve never returns a wallet address.

GET/v1/resolve/@{handle}scope profiles:resolve

You don't have to resolve before paying — every payment resolves server-side at creation and refuses anything that isn't VERIFIED. Use resolve to preview a recipient in your own UI, or to check a list of winners before a payout.

Parameters
handlepathrequired
The Fomo handle, with or without the @ (@lyra, lyra). Case-insensitive.
assetquery · USDG | ETHoptional
Only count destinations that accept this asset. Omit to see everything the destination accepts.
const r = await fp.resolve("@lyra", { asset: "USDG" });

if (r.state === "VERIFIED") {
  // FomoPay Ready: payable in USDG on Robinhood Chain
  showRecipient(r.profile.handle, r.profile.display_name, r.profile.avatar_url, r.warnings);
}
200 OK
{
  "profile": {
    "id": "fp_2b4d6f8h0k2m4p6r8t0v",
    "handle": "@lyra",
    "verified": true,
    "display_name": "Lyra Okoye",
    "avatar_url": null,
    "sandbox": false
  },
  "state": "VERIFIED",
  "payouts": [
    { "network": "robinhood", "asset_support": ["ETH", "USDG"], "status": "verified" }
  ],
  "warnings": [
    { "code": "NEW_RECIPIENT", "message": "First payment to @lyra from you. Double-check it's the right person." }
  ]
}

Response

profile.idstringrequired
FomoPay's id for the identity (fp_…) — never the upstream Fomo id.
profile.handlestringrequired
Display form with @, original casing.
profile.verifiedbooleanrequired
true only when the identity is FomoPay Ready: it has a payout wallet FomoPay verified on Robinhood Chain that accepts the asset. It is not a claim that Fomo verified the person.
profile.display_name · avatar_urlstring | nullrequired
Show them next to the handle before anyone confirms a payout.
profile.sandboxbooleanrequired
Test identity — label it “Sandbox”. Sandbox identities can't receive on mainnet.
stateIdentityStaterequired
VERIFIED, UNVERIFIED, NO_PAYOUT_WALLET, UNSUPPORTED_NETWORK or SUSPENDED — see below.
payouts[]arrayrequired
One entry per live destination: network ("robinhood", or e.g. "base" / "solana" for destinations FomoPay can't pay), asset_support and status (verified | unverified). No addresses.
warnings[]arrayrequired
Things a careful sender should know — see below. Show them to whoever approves the payment.

Identity states

FomoPay only pays VERIFIED identities. Every other state is refused at payment creation with a specific error — FomoPay never pays “just in case”.

StateWhat resolve showsA payment returns
VERIFIEDverified true, a robinhood payout that supports the assetCreated
UNVERIFIEDa robinhood payout with status unverified422 RECIPIENT_UNVERIFIED
NO_PAYOUT_WALLETverified false, payouts: []422 NO_PAYOUT_DESTINATION
UNSUPPORTED_NETWORKonly non-Robinhood payouts (e.g. base), or the asset isn't accepted422 UNSUPPORTED_NETWORK / 422 UNSUPPORTED_ASSET
SUSPENDEDpayouts: []422 RECIPIENT_SUSPENDED
NOT_FOUNDerror 404 RECIPIENT_NOT_FOUND (no state)404 RECIPIENT_NOT_FOUND
404 Not Found
{
  "error": {
    "code": "RECIPIENT_NOT_FOUND",
    "message": "We couldn't find that Fomo identity.",
    "request_id": "req_vjt0cnq2ft5xxw63",
    "details": { "handle": "@nobody_here" }
  }
}

Warnings

CodeMeaning
SIMILAR_HANDLELooks like an established identity (@Iyra with a capital i vs @lyra). details.similar_to names it. Confirm the recipient carefully.
RECENT_DESTINATION_CHANGEThe identity changed its payout wallet recently. Programmatic and vault payouts are held until the cooldown ends (details.cooldown_until, default 24 h).
NEW_RECIPIENTYour project has never paid this identity before.
SANDBOX_IDENTITYA test identity. Labelled "Sandbox" everywhere; can't receive on mainnet.
UPSTREAM_UNAVAILABLEThe Fomo identity provider couldn't be reached during this lookup. Try again shortly before paying.
200 OK — a lookalike
{
  "profile": { "id": "fp_9e1g3j5m7p9r1t3v5x7z", "handle": "@Iyra", "verified": true, "display_name": "Lyra Okoye", "avatar_url": null, "sandbox": false },
  "state": "VERIFIED",
  "payouts": [{ "network": "robinhood", "asset_support": ["ETH", "USDG"], "status": "verified" }],
  "warnings": [
    {
      "code": "SIMILAR_HANDLE",
      "message": "Similar handle detected: @lyra (Lyra Okoye). Confirm recipient carefully.",
      "details": { "similar_to": "lyra", "similar_to_profile_id": "fp_2b4d6f8h0k2m4p6r8t0v", "similar_to_display_name": "Lyra Okoye" }
    }
  ]
}

Privacy and limits

  • No addresses. /v1/resolve never returns a wallet address — not even masked. Payments carry a masked destination snapshot; full addresses are shown only to the people sending in the FomoPay app.
  • Purpose-bound. Resolution exists to pay people, not to build a handle → wallet directory. Each key may resolve a bounded number of distinct handles per day (repeats are free) and requests are rate-limited (120/min per key). Exceeding either returns 429 RATE_LIMITED.
  • FomoPay-known identities only. Handles that never set up FomoPay resolve to NO_PAYOUT_WALLET or NOT_FOUND; nothing is scraped.

Sandbox handles for testing

On the local stack these sandbox identities exercise every state: @lyra, @mia, @frog, @builder (verified), @Iyra (lookalike of @lyra), @pike (recent wallet change), @orbit (unverified), @kestrel (no payout wallet), @base_ben (Base only), @vex (suspended).

Show the avatar, display name and handle together before anyone confirms a payout — that's what catches a lookalike. Never render a check mark for anything but verified: true.