> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fomoscan.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Resolve a FOMO handle to the user and their verified wallet

> Looks a user up by their FOMO handle.

- **404** when we do not know the handle.
- A handle the user renamed to is found through their theses of the last 30 days;
  `handle` in the answer is the handle we hold for them.
- A **200** with both addresses null means we hold no verified wallet
  for this user.

A response that carries a wallet counts as one of the plan’s monthly reveals.

**Price:** 100 CU on a hit, 200 CU on a 404.



## OpenAPI

````yaml https://api.fomoscan.sh/openapi.json get /v2/user/handle/{handle}
openapi: 3.1.0
info:
  title: FomoScan Identity API
  version: 1.1.0
  description: >-
    Resolve a FOMO trader handle to their on-chain wallet addresses, and

    any wallet back to the traders behind it. Every returned address is a

    verified match.


    ## Authentication

    Send your API key as `Authorization: Bearer fsk_live_…` (or the

    `X-Api-Key` header). Enter it under Authentication at the top of this

    page to call any endpoint live.


    ```bash

    curl -s -H "Authorization: Bearer $KEY" \
      "https://api.fomoscan.sh/v2/user/handle/tradername"
    ```


    ## Response format

    A successful response is the record itself, as flat JSON. There is no

    wrapper to unwrap. Timestamps on thesis and PnL records are epoch

    milliseconds.


    ## Billing

    - A lookup that finds nothing is still charged, at the miss price stated on
    the endpoint.

    - `GET /v2/me` is free and reports your remaining units.

    - Errors that are our fault or your client’s (`401`, `403`, `429`, `5xx`)
    are not billed.

    - When the allowance is spent, calls return `402 QUOTA_EXCEEDED` until the
    counter resets.


    ## Free keys

    A free key reveals wallets for the sample set below and nobody else.

    Sample lookups cost no credits. Outside the set, a wallet lookup, or a

    handle or id lookup whose answer carries a wallet, returns

    `403 SAMPLE_SET_ONLY`. Profiles without a wallet and misses answer as

    they do for any key. A self-serve free key cannot open the WebSocket.


    - Handles: `frankdegods`, `unipcs`, `pointfarmcap`, `orangie`, `theveeman`

    - Wallets: `498g1rVnFcnjBjpfw1xyqA1WvgQXUU8RWuELjxkjAayQ`,
    `0x696d1265c8fc4f14797abebfae3c43ebfa9d8e28`,
    `2heJbC32Tpfcb3nbUb5ER61K11FGZVfVGtVnDm6LDogF`,
    `Beqv6dzTcjV2eodo8RRXCiCcnSYrS1vkQKhfqwHXqeit`,
    `83b2LMf12aLec92kur3duRA8VvUkLaXUtML31aCcZNCM`,
    `F5hkYsi8JxjyA2JHN5CA7MbnnhWubkXB2ZQB7Gkaxqs6`


    ## 404 NOT_FOUND

    A lookup that finds nothing answers `404` with the code `NOT_FOUND`. On

    a handle or id lookup it means we hold no user under that handle or id.

    On a wallet lookup it means we hold no verified link from that address

    to a trader. Treat it as "no answer today", cache the negative briefly

    and ask again later. A user we hold without a verified wallet answers

    `200` with both addresses `null`.


    ## Errors

    Every error uses one shape: `{ "error": { "code": "…", "message": "…" } }`.


    | HTTP | Code | Meaning |

    |---|---|---|

    | 400 | `VALIDATION_ERROR` | A malformed handle, address or query parameter.
    |

    | 400 | `BAD_REQUEST` | The request cannot be served as sent. |

    | 401 | `UNAUTHORIZED` | Missing or invalid API key. |

    | 402 | `QUOTA_EXCEEDED` | Out of credits. |

    | 402 | `REVEAL_LIMIT_REACHED` | The key’s reveal limit is reached. |

    | 403 | `FORBIDDEN` | The key may not perform this action. |

    | 403 | `FORBIDDEN_SCOPE` | The key is not provisioned for this endpoint. |

    | 403 | `FREE_TIER_DISABLED` | The key has no allowance. |

    | 403 | `SAMPLE_SET_ONLY` | A free key asked for a wallet outside the sample
    set. |

    | 403 | `WEBSOCKET_PLAN_REQUIRED` | The key’s plan has no WebSocket. It is
    included from Growth ($899), and legacy plans keep it. |

    | 404 | `NOT_FOUND` | No answer for the handle, id or wallet you asked
    about, or no such route. See the section above. |

    | 409 | `CONFLICT` | The request conflicts with one already accepted. |

    | 429 | `RATE_LIMITED` | Per-minute limit exceeded. Retry after `retryAfter`
    seconds. |

    | 500 | `INTERNAL_ERROR` | Our fault. Retry. If it persists, contact support
    with the path and the time. |

    | 503 | `OVERLOADED` | We are shedding load. Retry. |

    | 503 | `B2B_DISABLED` | The API is switched off on this deployment. |

    | 504 | `TIMEOUT` | The answer did not arrive in time. Retry. |


    A `429` also carries `retryAfter`, in seconds.


    ## Rate limits

    Each key has one per-minute request limit across every endpoint,

    readable from `GET /v2/me` as `ratePerMinute`. A per-IP burst ceiling

    sits behind it. Exceeding either returns `429 RATE_LIMITED`.


    ## Pricing

    Paid plans reach every REST endpoint. Plans differ in credits, request rate,

    wallet reveals and the WebSocket. Credits and CU are the same unit.


    | Plan | Free | Starter | Builder | Growth | Scale | Enterprise |

    | --- | --- | --- | --- | --- | --- | --- |

    | Price per month | $0 | $99 | $299 | $899 | $2,499 | Set in the contract |

    | Credits | 25,000 once, for 30 days | 1,000,000 a month | 5,000,000 a month
    | 20,000,000 a month | 75,000,000 a month | Set in the contract |

    | Requests per minute | 60 | 150 | 300 | 600 | 1,200 | Set in the contract |

    | Wallet reveals per month | Sample set only | 150 | 500 | 1,500 | 4,000 |
    No cap |

    | Price per 30,000-credit reveal | $0 on the sample set | $2.97 | $1.79 |
    $1.35 | $1.00 | Set in the contract |

    | WebSocket | No | No | No | Included | Included | Included |


    Keys on legacy plans keep the WebSocket access they already have.


    ### Wallet reveals

    A wallet reveal is an answer that returns a verified wallet. Each reveal
    counts

    against the plan’s wallet reveals for the month. It costs the credits of the

    endpoint that returned it:


    | Reveal endpoint | Credits per reveal |

    | --- | --- |

    | `GET /v2/user/handle/{handle}` | 100 |

    | `GET /v2/user/wallet/{address}` | 30,000 |

    | `GET /v2/user/id/{id}` | 100 |

    | `POST /v2/user/handle/{handle}/resolve` | 30,000 |

    | `GET /v2/user/handle/{handle}/pnl` | 30,000 |

    | `POST /v2/user/handles/pnl` | 30,000 per handle revealed |


    The price per 30,000-credit reveal in the plan table is what 30,000 credits

    cost on the plan. It applies to `GET /v2/user/wallet/{address}`, `POST
    /v2/user/handle/{handle}/resolve`, `GET /v2/user/handle/{handle}/pnl`, `POST
    /v2/user/handles/pnl`.

    A reveal on another endpoint costs that endpoint’s credits.


    ### Credit cost per endpoint


    | Endpoint | Credits |

    | --- | --- |

    | `GET /v2/user/handle/{handle}` | 100 CU on a hit, 200 CU on a 404. |

    | `GET /v2/user/wallet/{address}` | 30,000 CU on a hit, 200 CU on a 404. |

    | `GET /v2/user/id/{id}` | 100 CU on a hit, 200 CU on a 404. |

    | `POST /v2/user/handle/{handle}/resolve` | 30,000 CU on a hit, 200 CU on a
    202 or a 404. A paused lookup (202 with reason unavailable and retryable
    false) is not charged. |

    | `GET /v2/user/handle/{handle}/pnl` | 30,000 CU on a hit, 200 CU on any
    answer that is not ready, and on a 404. |

    | `POST /v2/user/handles/pnl` | 30,000 CU per entry answered ready, 200 CU
    per entry not ready and per handle in `missing`. |

    | `GET /v2/thesis` | 200 CU per 20 requested rows (`limit`, up to 100). An
    empty page costs the same as a full one. |

    | `GET /v2/thesis/token/{tokenAddress}` | 200 CU per 20 requested rows
    (`limit`, up to 100). An empty page costs the same as a full one. |

    | `GET /v2/thesis/user/{id}` | 200 CU per 20 requested rows (`limit`, up to
    100). An empty page costs the same as a full one. |

    | `GET /v2/thesis/user/{id}/token/{tokenAddress}` | 200 CU per 20 requested
    rows (`limit`, up to 100). An empty page costs the same as a full one. |

    | `GET /v2/me` | Free. |

    | `GET /v2/pump/user/wallet/{wallet}` | 10 CU per call. |

    | `GET /v2/pump/thesis` | 10 CU per call. |

    | `GET /v2/pump/thesis/token/{mint}` | 10 CU per call. |

    | `GET /v2/pump/thesis/wallet/{wallet}` | 10 CU per call. |

    | `GET /v2/pump/leaderboard/traders` | 10 CU per call. |

    | `GET /v2/pump/user/wallet/{wallet}/pnl` | 500 CU per call. |

    | `GET /v2/ws` | 20,000 CU per minute held open. |

    | `GET /v2/ws/pump` | 20,000 CU per minute held open. |


    ### Credit packs

    A pack adds credits on top of a plan. Pack credits do not expire, and they
    are

    spent after the plan’s monthly credits run out.


    | Pack | Price |

    | --- | --- |

    | 250,000 credits | $29 |

    | 1,000,000 credits | $115 |

    | 5,000,000 credits | $349 |

    | 20,000,000 credits | $1,049 |

    | 75,000,000 credits | $2,899 |


    ### Payment

    Plans are paid by card, and Apple Pay counts as a card. Credit packs are
    paid

    in crypto only, with no surcharge.


    ## Chains

    Wallet lookups take a Solana address or an EVM address. A verified EVM
    address

    is the same address on every EVM chain.


    Theses carry their token’s chain in `tokenNetwork`. This table shows the
    value

    the API returns for each chain we serve. Some chains arrive as a short name
    and

    some as a numeric chain id. Match on the exact value in the table.


    | Chain | `tokenNetwork` |

    | --- | --- |

    | Solana | `sol` |

    | Base | `base` |

    | BNB Chain | `bsc` |

    | Robinhood Chain | `robinhood` |

    | Ethereum | `eth` |

    | Arc | `5042` |

    | Monad | `143` |


    A thesis on a chain outside this table arrives as a short name or a numeric
    chain id.


    ## Breaking changes

    A breaking change removes or renames an endpoint, a field or an error code,
    or

    changes what a field means. We announce each one at least 3 days before it

    ships. The notice goes out on the changelog, on the Telegram announcements

    channel (https://t.me/scanfomo) and on every other channel we run.


    New fields can appear without notice. Ignore fields you do not recognise.
  contact:
    name: FomoScan
    url: https://fomoscan.sh
    email: fomoscan-support@proton.me
servers:
  - url: https://api.fomoscan.sh
    description: Production
security: []
tags:
  - name: Identities
    description: Resolve handles ↔ wallets.
  - name: Thesis Feed
    description: >-
      Trader "thesis" posts, newest first, by token, by author, or both. Ask
      with no `before` for the newest page. Clients MUST dedupe on `id`.
  - name: WebSocket
    description: >-
      The streaming surface. Everything above is a request you make; this is a
      connection you hold. It delivers the same thesis objects `Thesis Feed`
      returns.
  - name: Pump
    description: >-
      pump.fun lookups: a user by wallet, the global callout feed or one coin's
      or wallet's wall, and the PnL leaderboard. On pump.fun the wallet IS the
      account, so a wallet lookup here is a stored read, not a resolution.
  - name: Account
    description: 'Your key: entitlements and usage.'
paths:
  /v2/user/handle/{handle}:
    get:
      tags:
        - Identities
      summary: Resolve a FOMO handle to the user and their verified wallet
      description: >-
        Looks a user up by their FOMO handle.


        - **404** when we do not know the handle.

        - A handle the user renamed to is found through their theses of the last
        30 days;
          `handle` in the answer is the handle we hold for them.
        - A **200** with both addresses null means we hold no verified wallet
          for this user.

        A response that carries a wallet counts as one of the plan’s monthly
        reveals.


        **Price:** 100 CU on a hit, 200 CU on a 404.
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 64
          example: tradername
          in: path
          name: handle
          required: true
          description: FOMO username (case-insensitive; leading @ is stripped).
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - id
                  - handle
                  - name
                  - bio
                  - banner
                  - profilePicture
                  - twitter
                  - solanaAddress
                  - evmAddress
                properties:
                  id:
                    type: string
                    format: uuid
                    description: >-
                      Stable FOMO user id. Unlike `handle` it never changes, so
                      it is the key to store.
                  handle:
                    type: string
                    description: The canonical handle. Users rename — do not key on it.
                  name:
                    type:
                      - 'null'
                      - string
                    description: Display name.
                  bio:
                    type:
                      - 'null'
                      - string
                    description: >-
                      Profile blurb as written by the user, or null if they have
                      none.
                  banner:
                    type:
                      - 'null'
                      - string
                    description: >-
                      Cover photo URL on our image host, or null. The path is
                      `/a/<key>.webp`. A new picture gets a new URL. A picture
                      added in the last few minutes can show a neutral
                      placeholder until it is ready.
                  profilePicture:
                    type:
                      - 'null'
                      - string
                    description: >-
                      Avatar URL on our image host, or null. The path is
                      `/a/<key>.webp`. A new picture gets a new URL. A picture
                      added in the last few minutes can show a neutral
                      placeholder until it is ready.
                  twitter:
                    type:
                      - 'null'
                      - string
                    description: >-
                      Canonical X profile link, `https://x.com/<handle>`, or
                      null. Normalised from whatever the user typed on FOMO;
                      null when that could not be reduced to a plausible handle.
                      Self-declared and NOT verified by us — a claim, not a
                      proof.
                    example: https://x.com/tradername
                  solanaAddress:
                    type:
                      - 'null'
                      - string
                    description: Verified Solana address (base58), or null.
                  evmAddress:
                    type:
                      - 'null'
                      - string
                    description: Verified EVM address, `0x`-prefixed, or null.
                  socials:
                    type: array
                    description: >-
                      Verified social account links. Present only when social
                      account links are enabled on the API. Absent, not null,
                      when they are not.
                    items:
                      type: object
                      required:
                        - provider
                        - subject
                        - handle
                      properties:
                        provider:
                          type: string
                          description: >-
                            Platform identifier: 'x', 'telegram', 'youtube',
                            'reddit', etc.
                        subject:
                          type: string
                          description: >-
                            Platform-stable user id (e.g. Twitter numeric id
                            '12345678'). Stable across renames; use this as your
                            join key.
                        handle:
                          type:
                            - 'null'
                            - string
                          description: >-
                            Display username at verification time. May change;
                            do not key on it.
        '404':
          description: Default Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/def-0'
      security:
        - b2bApiKey: []
components:
  schemas:
    def-0:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Stable, lower-snake-case error code.
              enum:
                - BAD_REQUEST
                - B2B_DISABLED
                - CONFLICT
                - FORBIDDEN
                - FORBIDDEN_SCOPE
                - FREE_TIER_DISABLED
                - INTERNAL_ERROR
                - NOT_FOUND
                - OVERLOADED
                - QUOTA_EXCEEDED
                - RATE_LIMITED
                - REVEAL_LIMIT_REACHED
                - SAMPLE_SET_ONLY
                - TIMEOUT
                - UNAUTHORIZED
                - VALIDATION_ERROR
                - WEBSOCKET_PLAN_REQUIRED
            message:
              type: string
            retryAfter:
              type: integer
              description: Seconds; only on RATE_LIMITED.
            addUrl:
              type: string
              description: Hint URL, present on some NOT_FOUND responses.
      title: ErrorBody
  securitySchemes:
    b2bApiKey:
      type: http
      scheme: bearer
      description: >-
        B2B API key (`fsk_live_…` / `fsk_test_…`), issued by FomoScan. Also
        accepted via `X-Api-Key`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.