HANSEMPNL
PNL
DOCS

GMGN Data API

GMGN wallets with the name GMGN shows and the X account it names for each, its labels, and the realised PnL and trade count it published: one page read newest change first, one wallet lookup, 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/gmgn/traders — GMGN wallets, with the name and X GMGN gives them and its figures

Every GMGN wallet this store holds, newest change first: the name GMGN shows, the X account it names for the wallet, its labels, and the realised PnL and trade count GMGN published where they were read. Filter by 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.
x_handle{"type":"string","pattern":"^@?[A-Za-z0-9_]{1,15}$"}An X username, with or without @, any case: the wallets GMGN names that account for.

Returns the GmgnTraderPage schema below.

GET /v1/gmgn/wallet/{address} — One GMGN wallet

One wallet's record, or wallet: null when this store holds none for it (a 200, never a 404).

No query parameters: the wallet is the path's {address}.

Returns the GmgnWalletAnswer schema below.

curl -H "Authorization: Bearer $KEY" "https://api.hansem.io/v1/gmgn/traders?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. The name, the X username and the labels are GMGN's own words for the wallet: GMGN names an X account for a wallet, and that is its word, never a verification of who holds the account. The PnL and trade figures are GMGN's own as of figures_at; a wallet whose figures were never read carries null figures and a null figures_at.

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.

GmgnTrader
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "wallet": {
      "type": "string",
      "description": "The wallet, Solana base58 as GMGN sent it. The key of the record."
    },
    "chain": {
      "type": "string",
      "const": "solana"
    },
    "name": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The name GMGN shows for the wallet; null when it shows none."
    },
    "x_handle": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The X username GMGN names for the wallet, lower-cased, without @. GMGN's word for it, never a verification of who holds the account."
    },
    "x_name": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The X display name GMGN shows beside it."
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "GMGN's own labels for the wallet as last read; empty when none were read."
    },
    "realized_pnl_24h_usd": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "description": "The realised PnL GMGN published for the wallet over 24 hours, as of figures_at; null where it was not read."
    },
    "realized_pnl_7d_usd": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "description": "The same over 7 days."
    },
    "realized_pnl_30d_usd": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "description": "The same over 30 days."
    },
    "trades_7d": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        {
          "type": "null"
        }
      ],
      "description": "Buys plus sells GMGN published for the wallet over 7 days, as of figures_at."
    },
    "last_active_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 wallet's last trade, as GMGN published it."
    },
    "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 figures above were read from GMGN; null when no figure has been read for this wallet."
    },
    "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",
    "name",
    "x_handle",
    "x_name",
    "tags",
    "realized_pnl_24h_usd",
    "realized_pnl_7d_usd",
    "realized_pnl_30d_usd",
    "trades_7d",
    "last_active_at",
    "figures_at",
    "seen_at"
  ],
  "additionalProperties": false
}
GmgnTraderPage
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "records": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "wallet": {
            "type": "string",
            "description": "The wallet, Solana base58 as GMGN sent it. The key of the record."
          },
          "chain": {
            "type": "string",
            "const": "solana"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The name GMGN shows for the wallet; null when it shows none."
          },
          "x_handle": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The X username GMGN names for the wallet, lower-cased, without @. GMGN's word for it, never a verification of who holds the account."
          },
          "x_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The X display name GMGN shows beside it."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "GMGN's own labels for the wallet as last read; empty when none were read."
          },
          "realized_pnl_24h_usd": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The realised PnL GMGN published for the wallet over 24 hours, as of figures_at; null where it was not read."
          },
          "realized_pnl_7d_usd": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The same over 7 days."
          },
          "realized_pnl_30d_usd": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The same over 30 days."
          },
          "trades_7d": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ],
            "description": "Buys plus sells GMGN published for the wallet over 7 days, as of figures_at."
          },
          "last_active_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 wallet's last trade, as GMGN published it."
          },
          "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 figures above were read from GMGN; null when no figure has been read for this wallet."
          },
          "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",
          "name",
          "x_handle",
          "x_name",
          "tags",
          "realized_pnl_24h_usd",
          "realized_pnl_7d_usd",
          "realized_pnl_30d_usd",
          "trades_7d",
          "last_active_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
}
GmgnWalletAnswer
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "wallet": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "wallet": {
              "type": "string",
              "description": "The wallet, Solana base58 as GMGN sent it. The key of the record."
            },
            "chain": {
              "type": "string",
              "const": "solana"
            },
            "name": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The name GMGN shows for the wallet; null when it shows none."
            },
            "x_handle": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The X username GMGN names for the wallet, lower-cased, without @. GMGN's word for it, never a verification of who holds the account."
            },
            "x_name": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The X display name GMGN shows beside it."
            },
            "tags": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "GMGN's own labels for the wallet as last read; empty when none were read."
            },
            "realized_pnl_24h_usd": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The realised PnL GMGN published for the wallet over 24 hours, as of figures_at; null where it was not read."
            },
            "realized_pnl_7d_usd": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The same over 7 days."
            },
            "realized_pnl_30d_usd": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The same over 30 days."
            },
            "trades_7d": {
              "anyOf": [
                {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                {
                  "type": "null"
                }
              ],
              "description": "Buys plus sells GMGN published for the wallet over 7 days, as of figures_at."
            },
            "last_active_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 wallet's last trade, as GMGN published it."
            },
            "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 figures above were read from GMGN; null when no figure has been read for this wallet."
            },
            "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",
            "name",
            "x_handle",
            "x_name",
            "tags",
            "realized_pnl_24h_usd",
            "realized_pnl_7d_usd",
            "realized_pnl_30d_usd",
            "trades_7d",
            "last_active_at",
            "figures_at",
            "seen_at"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    },
    "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": [
    "wallet",
    "read_at"
  ],
  "additionalProperties": false
}