HANSEMPNL
PNL
DOCS

pump.fun Data API

pump.fun accounts, where the wallet IS the account: the username, the X account the profile declares, and the account's calls over 30 days: one page read newest change first, filtered by wallet, username or X, on the data key you already hold.

OpenAPI 3.1 JSON ↗ · FOMO Data API · Data key access · Auth · limits · errors

Authentication & allowance

The FOMO Data API's key, plan and allowance, unchanged: send Authorization: Bearer sk_ansem_… or the same key in X-Api-Key; a data key on plan builder or above; every served call counts once against the key's per-minute window and daily ceiling, shared with every FOMO door, and carries the same X-RateLimit headers. No call here reaches an upstream: every answer is read from our own store.

Endpoints

GET /v1/pump/users — pump.fun accounts: the wallet, its username and declared X, its calls

Every pump.fun account this store holds, newest change first: the wallet (on pump.fun the wallet is the account), the username, the X the profile declares, and the account's calls over 30 days where the caller ledger read them. Filter by wallet, username or X username.

QueryType · boundsMeaning
limit{"type":"integer","minimum":1,"maximum":100}Records per page, 1..100; 50 when absent.
cursor{"type":"string","minLength":1,"maxLength":1024}The previous page's next_cursor, verbatim. Bound to the filters it was minted under: any other filter set is a 400 naming cursor.
wallet{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$"}A wallet, Solana base58 exactly: on pump.fun the wallet is the account.
username{"type":"string","minLength":1,"maxLength":64}A pump.fun username, any case.
x_handle{"type":"string","pattern":"^@?[A-Za-z0-9_]{1,15}$"}An X username, with or without @, any case: the accounts whose pump.fun profile declares it.

Returns the PumpUserPage schema below.

curl -H "Authorization: Bearer $KEY" "https://api.hansem.io/v1/pump/users?limit=50"

One cursor law

Pages are newest change first. While next_cursor is a string, hand it back verbatim as cursor for the next page; null is the last page. A cursor is opaque and signed, bound to the door and the filters it was minted under: any other combination is a 400 naming cursor, never silently page one.

What a record is

Every field is present on every record; a value nobody read is null, never invented. On pump.fun the wallet is the account. The X username is the one the account's profile declares; pump.fun does not verify it. The call figures are pump.fun's own as of figures_at; calls_complete false means the count is a floor.

Coverage — what this store holds

Every page carries coverage: how many wallets this store holds for the platform, how many of them carry an X username, and the newest change to any of them. An empty page with HTTP 200 is a real answer: read it against coverage, never as an outage. Solana wallets only.

Errors & retries

One envelope: { error: { code, message, type, request_id } }. The message names the refused parameter, never its value. A wallet this store holds nothing for is a 200 with wallet: null, never a 404.

HTTPCodeMeaningNext action
400invalid_requestA parameter was refused; the message names it, never its value. A cursor minted under other filters or the other order lands here.Fix the parameter. For a cursor: send it with exactly the filters and order it was minted under, or start a new walk.
401missing_api_key · invalid_api_key · revoked_api_keyNo key, a key this system never issued, or one that was revoked.Send Authorization: Bearer <your data key>.
403permission_deniedThe key is not a data key on plan builder or above; required_plan names the plan.Use the data key issued for this API.
404not_foundNo route answers the path — an unknown route, never missing data: a token, author or person nobody stored answers 200.Check the method and the path against this reference.
405method_not_allowedThe allow header names the verb the door takes: GET on every read, POST on the resolve.Use the verb the allow header names.
429rate_limit_exceeded · quota_exceededThe key's per-minute window, or its daily ceiling. Retry-After says when.Wait Retry-After seconds. Changing doors does not reset the window — every door shares one allowance.
503service_unavailableThe store or the usage ledger could not be read or written; nothing was served, and nothing was counted against you.Keep your cursor and retry after Retry-After. This is never an empty page.

Schemas

Field types, nullability and enums, as the OpenAPI document carries them. Every schema is pinned by a test to what the doors actually serve.

PumpUser
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "wallet": {
      "type": "string",
      "description": "The account's wallet, Solana base58: on pump.fun the wallet is the account."
    },
    "chain": {
      "type": "string",
      "const": "solana"
    },
    "username": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "pump.fun's username for the account; null when it published none."
    },
    "x_handle": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The X username the account's pump.fun profile declares, lower-cased, without @. Declared by the user; pump.fun does not verify it."
    },
    "profile_image": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The picture pump.fun published for the account."
    },
    "followers": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        {
          "type": "null"
        }
      ],
      "description": "The follower count pump.fun published beside the declared X."
    },
    "calls_30d": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        {
          "type": "null"
        }
      ],
      "description": "Calls the account made on pump.fun inside the 30 days before figures_at, as pump.fun lists them."
    },
    "ran_2x_30d": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        {
          "type": "null"
        }
      ],
      "description": "Of those, the calls whose coin reached twice its called market cap, by pump.fun's own peak figure."
    },
    "above_entry_30d": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        {
          "type": "null"
        }
      ],
      "description": "Of those, the calls still at or above their called market cap at figures_at."
    },
    "best_peak_multiple_30d": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "description": "The highest peak multiple among those calls, pump.fun's figure."
    },
    "calls_complete": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "description": "false when the read stopped before the window's end, so calls_30d is a floor."
    },
    "last_called_at": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
        },
        {
          "type": "null"
        }
      ],
      "description": "The account's newest call pump.fun lists."
    },
    "figures_at": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
        },
        {
          "type": "null"
        }
      ],
      "description": "When the call figures were read from pump.fun."
    },
    "seen_at": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
      "description": "When the identity words above last changed in this store."
    }
  },
  "required": [
    "wallet",
    "chain",
    "username",
    "x_handle",
    "profile_image",
    "followers",
    "calls_30d",
    "ran_2x_30d",
    "above_entry_30d",
    "best_peak_multiple_30d",
    "calls_complete",
    "last_called_at",
    "figures_at",
    "seen_at"
  ],
  "additionalProperties": false
}
PumpUserPage
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "records": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "wallet": {
            "type": "string",
            "description": "The account's wallet, Solana base58: on pump.fun the wallet is the account."
          },
          "chain": {
            "type": "string",
            "const": "solana"
          },
          "username": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "pump.fun's username for the account; null when it published none."
          },
          "x_handle": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The X username the account's pump.fun profile declares, lower-cased, without @. Declared by the user; pump.fun does not verify it."
          },
          "profile_image": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The picture pump.fun published for the account."
          },
          "followers": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ],
            "description": "The follower count pump.fun published beside the declared X."
          },
          "calls_30d": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ],
            "description": "Calls the account made on pump.fun inside the 30 days before figures_at, as pump.fun lists them."
          },
          "ran_2x_30d": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ],
            "description": "Of those, the calls whose coin reached twice its called market cap, by pump.fun's own peak figure."
          },
          "above_entry_30d": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ],
            "description": "Of those, the calls still at or above their called market cap at figures_at."
          },
          "best_peak_multiple_30d": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The highest peak multiple among those calls, pump.fun's figure."
          },
          "calls_complete": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "false when the read stopped before the window's end, so calls_30d is a floor."
          },
          "last_called_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
              },
              {
                "type": "null"
              }
            ],
            "description": "The account's newest call pump.fun lists."
          },
          "figures_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the call figures were read from pump.fun."
          },
          "seen_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
            "description": "When the identity words above last changed in this store."
          }
        },
        "required": [
          "wallet",
          "chain",
          "username",
          "x_handle",
          "profile_image",
          "followers",
          "calls_30d",
          "ran_2x_30d",
          "above_entry_30d",
          "best_peak_multiple_30d",
          "calls_complete",
          "last_called_at",
          "figures_at",
          "seen_at"
        ],
        "additionalProperties": false
      }
    },
    "next_cursor": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Hand it back as cursor for the next page; null when this page was the last."
    },
    "filters": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ]
      }
    },
    "coverage": {
      "type": "object",
      "properties": {
        "wallets": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991,
          "description": "Wallets this store holds for the platform."
        },
        "with_x": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991,
          "description": "Of those, the wallets carrying an X username."
        },
        "newest_seen_at": {
          "anyOf": [
            {
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
            },
            {
              "type": "null"
            }
          ],
          "description": "The newest change to any of them."
        }
      },
      "required": [
        "wallets",
        "with_x",
        "newest_seen_at"
      ],
      "additionalProperties": false
    },
    "read_at": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
    }
  },
  "required": [
    "records",
    "next_cursor",
    "filters",
    "coverage",
    "read_at"
  ],
  "additionalProperties": false
}