---
title: "GMGN scraper"
description: "Scrape GMGN trending tokens as JSON: price, market cap, liquidity, volume, swaps, holders and security flags. One API request from Python, Node.js, the CLI or MCP."
canonical: https://www.zenrows.com/scrape/gmgn
updated: 2026-10-20
---

# GMGN scraper

The Zenrows GMGN scraper returns the GMGN trending token ranking as JSON: token address, symbol, price, market cap, liquidity, volume, swaps, buys and sells, holder count, top 10 holder rate, launchpad and security flags. Fetch in Adaptive Stealth Mode opens GMGN's own data feed, and Extract reads token pages. Run it from an API call, the CLI or an AI agent.

- Site: gmgn.ai
- Returns: Trending tokens, prices, liquidity, holders and security flags

## Run it: GMGN trending tokens in, JSON out

```json Input
{
  "url": "https://gmgn.ai/defi/quotation/v1/rank/sol/swaps/1h?orderby=swaps&direction=desc",
  "mode": "auto"
}
```

```json Output
{
  "code": 0,
  "message": "success",
  "data": {
    "rank": [
      {
        "chain": "sol",
        "address": "giUU7i2mBB6S9sFsSpeQFmNh8knRyk5UsLmzkhPpump",
        "name": "FomoFamily | Offical Team",
        "symbol": "FOMO",
        "price": 0.000756423,
        "price_change_percent5m": 9.67161,
        "price_change_percent1h": 6676.86,
        "volume": 63819.7,
        "liquidity": 71023.2,
        "market_cap": 752480,
        "history_highest_market_cap": 752705,
        "swaps": 38439,
        "buys": 22028,
        "sells": 16411,
        "holder_count": 2520,
        "top_10_holder_rate": 0.0043,
        "open_timestamp": 1792459094,
        "launchpad_platform": "Pump.fun",
        "exchange": "pump_amm",
        "renounced_mint": 1,
        "renounced_freeze_account": 1,
        "burn_status": "burn",
        "is_honeypot": 0,
        "is_wash_trading": false,
        "sniper_count": 7,
        "smart_degen_count": 1,
        "bot_degen_rate": 0.7642,
        "rank": 1
      }
    ]
  }
}
```

Request and output of a live call to GMGN's trending token feed (Solana, last hour, sorted by swaps) on Oct 20, 2026, trimmed to one token and its main fields. The full response held 100 tokens.

## What data can you scrape from GMGN?

GMGN's token pages draw their numbers from GMGN's own JSON feeds, and Zenrows fetches those feeds directly. One request to the trending ranking returns every token on the board with these fields, among others.

| Field | What it holds | Example |
|---|---|---|
| `data.rank[].address` | The token's contract address, the key for every other lookup | `giUU7i2mBB6S9sFsSpeQFmNh8knRyk5UsLmzkhPpump` |
| `data.rank[].symbol` | Ticker shown on GMGN | `FOMO` |
| `data.rank[].name` | Token name as its creator set it | `the collectooor` |
| `data.rank[].chain` | Chain of the ranking | `sol` |
| `data.rank[].price` | Price in USD | `0.000756423` |
| `data.rank[].price_change_percent1h` | Price change over the last hour, in percent (also `1m` and `5m`) | `6676.86` |
| `data.rank[].market_cap` | Market cap in USD, with the all-time high in `history_highest_market_cap` | `752480` |
| `data.rank[].liquidity` | Pool liquidity in USD, next to `initial_liquidity` | `71023.2` |
| `data.rank[].volume` | Trading volume in USD over the ranking window | `63819.7` |
| `data.rank[].swaps` | Number of swaps, split into `buys` and `sells` | `38439` |
| `data.rank[].holder_count` | Wallets holding the token | `2520` |
| `data.rank[].top_10_holder_rate` | Share of supply held by the 10 largest wallets | `0.0043` |
| `data.rank[].launchpad_platform` | Where the token launched | `Pump.fun` |
| `data.rank[].open_timestamp` | Pool open time, Unix seconds | `1792459094` |
| `data.rank[].renounced_mint` | Whether minting is renounced (1 or 0), next to `renounced_freeze_account` | `1` |
| `data.rank[].is_honeypot` | GMGN's honeypot flag | `0` |
| `data.rank[].burn_status` | Liquidity burn status | `burn` |
| `data.rank[].smart_degen_count` | Wallets GMGN tags as smart money holding the token, next to `sniper_count` and `bot_degen_rate` | `127` |

## How to scrape GMGN with Zenrows

1. **Create a free Zenrows account** and copy your API key from the dashboard.
2. **Start from the trending feed.** `https://gmgn.ai/defi/quotation/v1/rank/sol/swaps/1h?orderby=swaps&direction=desc` is the Solana ranking for the last hour, sorted by swaps. It answers with JSON already, so Adaptive Stealth Mode alone is enough.
3. **Read `data.rank`** from the response. Each item is one token, ranked, with price, liquidity, holders and the security flags.
4. **Open a token page** (`https://gmgn.ai/sol/token/<address>`) with Adaptive Stealth Mode and Extract when you want that page's content for one address from the ranking.
5. **Schedule the feed or send a list to Batch** once one request returns what you need.

```python Python
# pip install requests
import requests

API = "https://api.zenrows.com/v1/"
KEY = "YOUR_ZENROWS_API_KEY"

# 1. The trending ranking: GMGN answers with JSON, so Fetch alone is enough
feed = requests.get(API, params={
    "apikey": KEY,
    "url": "https://gmgn.ai/defi/quotation/v1/rank/sol/swaps/1h?orderby=swaps&direction=desc",
    "mode": "auto",          # Adaptive Stealth Mode
}, timeout=180)
feed.raise_for_status()

for token in feed.json()["data"]["rank"][:10]:
    print(token["rank"], token["symbol"], token["price"],
          token["market_cap"], token["holder_count"], token["is_honeypot"])

# 2. One token page, with Extract
page = requests.get(API, params={
    "apikey": KEY,
    "url": "https://gmgn.ai/sol/token/giUU7i2mBB6S9sFsSpeQFmNh8knRyk5UsLmzkhPpump",
    "mode": "auto",
    "extract": "auto",       # structured JSON in "parsed"
}, timeout=180)
print(page.json()["parsed"])
```

```javascript Node.js
// Node 18+ (built-in fetch)
const params = new URLSearchParams({
  apikey: "YOUR_ZENROWS_API_KEY",
  url: "https://gmgn.ai/defi/quotation/v1/rank/sol/swaps/1h?orderby=swaps&direction=desc",
  mode: "auto",
});

const response = await fetch(`https://api.zenrows.com/v1/?${params}`, {
  signal: AbortSignal.timeout(180_000),
});
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);

const { data } = await response.json();
const safe = data.rank.filter((t) => t.is_honeypot === 0 && t.renounced_mint === 1);
console.table(safe.map((t) => ({ symbol: t.symbol, mcap: t.market_cap, holders: t.holder_count })));

// A token page uses the same call with extract: "auto"
const page = new URLSearchParams({
  apikey: "YOUR_ZENROWS_API_KEY",
  url: "https://gmgn.ai/sol/token/giUU7i2mBB6S9sFsSpeQFmNh8knRyk5UsLmzkhPpump",
  mode: "auto",
  extract: "auto",
});
const { parsed } = await (await fetch(`https://api.zenrows.com/v1/?${page}`)).json();
console.log(parsed);
```

```bash cURL
# The trending ranking as JSON
curl "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fgmgn.ai%2Fdefi%2Fquotation%2Fv1%2Frank%2Fsol%2Fswaps%2F1h%3Forderby%3Dswaps%26direction%3Ddesc&mode=auto"

# A token page with Extract
curl "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fgmgn.ai%2Fsol%2Ftoken%2FgiUU7i2mBB6S9sFsSpeQFmNh8knRyk5UsLmzkhPpump&mode=auto&extract=auto"
```

```python Python SDK
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_ZENROWS_API_KEY")
response = client.get(
    "https://gmgn.ai/defi/quotation/v1/rank/sol/swaps/1h?orderby=swaps&direction=desc",
    params={"mode": "auto"},
)
rank = response.json()["data"]["rank"]
movers = sorted(rank, key=lambda t: t["volume"], reverse=True)[:5]
for t in movers:
    print(t["symbol"], t["volume"], t["liquidity"], t["top_10_holder_rate"])

# Token pages take Extract as well
page = client.get(
    "https://gmgn.ai/sol/token/ESnW5ZbLmoEAg2QEMxnMsY9R3aS8Kw58HJacYURmpump",
    params={"mode": "auto", "extract": "auto"},
)
print(page.json()["parsed"])
```

## Input

The scraper takes one GMGN URL per request. For the trending feed, Adaptive Stealth Mode is the whole configuration, because GMGN already answers in JSON. For token pages, add Extract.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `url` | string | required | The GMGN trending feed (`/defi/quotation/v1/rank/sol/swaps/1h?…`) or a token page (`/sol/token/<address>`) |
| `mode` | string | `auto` | Adaptive Stealth Mode: starts with the lightest setup and adds rendering and protected-site handling only when GMGN needs them |
| `extract` | string | none | Set to `auto` on token pages to get the page's fields as JSON in `parsed`. Leave it out for the feed, which is JSON already |
| `wait_for` | string | none | A CSS selector to wait for on a token page before it is read |
| `session_id` | integer | none | Keep the same session across several requests, up to 10 minutes, for a run of token pages |

```json Batch input
{
  "type": "regular",
  "status": "closed",
  "zenrows_params": {
    "mode": "auto"
  },
  "tasks": [
    { "url": "https://gmgn.ai/defi/quotation/v1/rank/sol/swaps/1h?orderby=swaps&direction=desc", "external_id": "sol-trending-1h" },
    { "url": "https://gmgn.ai/sol/token/giUU7i2mBB6S9sFsSpeQFmNh8knRyk5UsLmzkhPpump", "external_id": "FOMO", "zenrows_params": { "extract": "auto" } },
    { "url": "https://gmgn.ai/sol/token/ESnW5ZbLmoEAg2QEMxnMsY9R3aS8Kw58HJacYURmpump", "external_id": "COLLECTOOOR", "zenrows_params": { "extract": "auto" } }
  ]
}
```

## Output

The trending feed comes back as GMGN's own JSON: a `code`, a `message` and a `data.rank` array, one object per token, in ranking order. Every token carries the same keys, so the array loads straight into a table. The record below is another token from the same live response, kept with more of its fields.

```json Trending ranking
{
  "code": 0,
  "message": "success",
  "data": {
    "rank": [
      {
        "chain": "sol",
        "address": "ESnW5ZbLmoEAg2QEMxnMsY9R3aS8Kw58HJacYURmpump",
        "name": "the collectooor",
        "symbol": "COLLECTOOOR",
        "logo": "https://gmgn.ai/external-res/5b7dcdb49bb36bfdee25206e4389dd8a_v2.webp",
        "price": 0.000368652,
        "price_change_percent": -39.4031,
        "price_change_percent1m": 8.69176,
        "price_change_percent5m": 15.9375,
        "price_change_percent1h": -39.4031,
        "volume": 457188,
        "liquidity": 63425.3,
        "market_cap": 358805,
        "total_supply": 973290295,
        "initial_liquidity": 24360.8,
        "history_highest_market_cap": 1141503,
        "swaps": 6005,
        "buys": 3340,
        "sells": 2665,
        "holder_count": 3318,
        "top_10_holder_rate": 0.1766,
        "open_timestamp": 1792436349,
        "launchpad": "pump",
        "launchpad_platform": "Pump.fun",
        "exchange": "pump_amm",
        "renounced_mint": 1,
        "renounced_freeze_account": 1,
        "burn_status": "burn",
        "creator_token_status": "creator_close",
        "is_wash_trading": false,
        "rug_ratio": 0.1,
        "sniper_count": 0,
        "smart_degen_count": 127,
        "renowned_count": 7,
        "bundler_rate": 0.2639,
        "bot_degen_rate": 0.53,
        "dev_team_hold_rate": 0,
        "is_honeypot": 0,
        "score": 0.704568,
        "rank": 11
      }
    ]
  }
}
```

| Group | Fields in each token |
|---|---|
| Identity | `address`, `symbol`, `name`, `chain`, `logo`, `creator`, `twitter_username`, `website`, `telegram` |
| Market | `price`, `price_change_percent1m`, `price_change_percent5m`, `price_change_percent1h`, `market_cap`, `history_highest_market_cap`, `liquidity`, `initial_liquidity`, `volume`, `total_supply` |
| Activity | `swaps`, `buys`, `sells`, `holder_count`, `visiting_count`, `hot_level`, `score`, `rank` |
| Launch | `launchpad`, `launchpad_platform`, `exchange`, `migrated_pool_exchange`, `open_timestamp`, `creation_timestamp` |
| Risk flags | `renounced_mint`, `renounced_freeze_account`, `burn_status`, `is_honeypot`, `is_wash_trading`, `rug_ratio`, `top_10_holder_rate`, `dev_team_hold_rate`, `bundler_rate` |
| Wallet mix | `smart_degen_count`, `renowned_count`, `sniper_count`, `bot_degen_count`, `bot_degen_rate`, `top70_sniper_hold_rate` |

Need a spreadsheet? Load `data.rank` into pandas with `pd.DataFrame(...)` and write CSV or Parquet. Need the numbers in a prompt? Pass the trimmed array to your model as it is.

## Scrape GMGN from your coding agent

Claude Code, Cursor, Codex and any MCP client can pull the GMGN ranking from a prompt.

The agent sends the same Fetch request a developer would, reads the `data.rank` array and works with the tokens in it. Connect the Zenrows MCP server once, or give the agent the CLI.

```bash Connect the MCP server (Claude Code)
claude mcp add zenrows -e ZENROWS_API_KEY=YOUR_ZENROWS_API_KEY -- npx -y @zenrows/mcp
```

```json MCP config (Cursor, Claude Desktop, Windsurf)
{
  "mcpServers": {
    "zenrows": {
      "command": "npx",
      "args": ["-y", "@zenrows/mcp"],
      "env": { "ZENROWS_API_KEY": "YOUR_ZENROWS_API_KEY" }
    }
  }
}
```

```bash Or run the CLI
npx -y @zenrows/cli init
zenrows fetch "https://gmgn.ai/defi/quotation/v1/rank/sol/swaps/1h?orderby=swaps&direction=desc" --out gmgn-trending.json
zenrows extract "https://gmgn.ai/sol/token/giUU7i2mBB6S9sFsSpeQFmNh8knRyk5UsLmzkhPpump"
```

```text Then ask your agent
Use Zenrows to fetch this GMGN ranking:
https://gmgn.ai/defi/quotation/v1/rank/sol/swaps/1h?orderby=swaps&direction=desc
Keep the tokens with is_honeypot 0, renounced_mint 1 and a top_10_holder_rate
under 0.2, and return symbol, address, market_cap, liquidity and holder_count
as a table sorted by liquidity.
```

## Scrape GMGN at scale with Batch and Crawl

**Batch** runs many GMGN URLs as one job, in parallel, with your own ID on each result. Put the trending feed and the token pages you follow in one job, tag each token with its symbol or address, and rerun the job on your schedule to keep a time series of each token's numbers.

**Crawl** follows links from a start page on gmgn.ai and returns every page it reaches. Start it on the Solana home view, keep the links that contain `/sol/token/`, and it collects the token pages linked from the board. Send that list to Batch with Extract.

```bash Batch (cURL)
curl -X POST "https://async.api.zenrows.com/v1/jobs" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "regular",
    "status": "closed",
    "zenrows_params": { "mode": "auto", "extract": "auto" },
    "tasks": [
      { "url": "https://gmgn.ai/sol/token/giUU7i2mBB6S9sFsSpeQFmNh8knRyk5UsLmzkhPpump", "external_id": "FOMO" },
      { "url": "https://gmgn.ai/sol/token/ESnW5ZbLmoEAg2QEMxnMsY9R3aS8Kw58HJacYURmpump", "external_id": "COLLECTOOOR" }
    ]
  }'

# Read the results when the job finishes
curl "https://async.api.zenrows.com/v1/jobs/JOB_ID/results?status=successful" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY"
```

```bash Batch (CLI)
# tokens.jsonl: one {"url": "...", "external_id": "...", "extract": "auto"} per line
zenrows batch create tokens.jsonl --wait
zenrows batch results <job-id> --out gmgn-tokens.jsonl
```

```bash Crawl (cURL)
curl -X POST "https://api.zenrows.com/v1/crawls" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://gmgn.ai/?chain=sol",
    "depth": 1,
    "max_pages": 100,
    "include_patterns": ["/sol/token/"]
  }'
```

**Scheduled jobs** run the same Batch job on a timetable, on Zenrows' side: every few hours, once a day, at set times on chosen days, or once at a future date. Each run keeps its own results, a webhook can tell your app when a run finishes, and you can pause or resume the schedule at any time, with no cron server to keep alive.

```bash Scheduled job (cURL)
# Runs every day on Zenrows' side; each run keeps its own results
curl -X POST "https://async.api.zenrows.com/v1/jobs" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "type": "scheduled",
      "status": "closed",
      "schedule": {
        "rate": {
          "every": 1,
          "unit": "day"
        }
      },
      "zenrows_params": {
        "mode": "auto"
      },
      "tasks": [
        {
          "url": "https://gmgn.ai/defi/quotation/v1/rank/sol/swaps/1h?orderby=swaps&direction=desc",
          "external_id": "gmgn"
        }
      ]
    }'

# Or at set times: "schedule": { "calendar": { "times_of_day": ["09:00"],
#   "cadence": { "weekly": { "days": ["mon", "thu"] } } }, "timezone": "Europe/Madrid" }
```

## What teams do with GMGN data

| Use case | Data they pull | Who runs it |
|---|---|---|
| Memecoin discovery | New entries in the ranking, `open_timestamp`, launchpad, swaps and holder growth between runs | Crypto researchers and on-chain analysts |
| Token screening | Liquidity, market cap, top 10 holder rate, honeypot and renounced flags as filters | Quant and trading desks |
| Smart-money tracking | `smart_degen_count`, `renowned_count`, `sniper_count` and bot share per token over time | Signal and alpha research teams |
| Trading bot inputs | The ranking as a JSON feed, polled on a schedule, joined on token address | Bot and tooling developers |
| Risk checks | `rug_ratio`, `bundler_rate`, `dev_team_hold_rate` and burn status before a token goes on a watchlist | Risk and compliance teams at crypto firms |
| Dashboards and alerts | Price changes at 1m, 5m and 1h, volume and liquidity, written to a database each run | Data teams and community analysts |

The data describes tokens; what you do with it is your call. Nothing here is trading advice.

## Tips for scraping GMGN

- **Take the feed, not the screen.** The trending board on gmgn.ai is drawn from the feed URL above, so requesting the feed gives the same numbers as clean JSON, with no parsing.
- **Key everything on `address`.** Symbols and names repeat across tokens, and many copy famous brands. The contract address is the only stable ID, so use it as the `external_id` in Batch and as the join key in your database.
- **Store the timestamp of each run.** The ranking reflects the last hour at the moment you call it. Save your own fetch time next to each row to build a history of price, holders and liquidity.
- **Convert Unix times once.** `open_timestamp` and `creation_timestamp` are seconds since 1970. In Python, `datetime.fromtimestamp(t, tz=timezone.utc)` turns them into dates.
- **Read the rates as fractions.** `top_10_holder_rate`, `bot_degen_rate` and `bundler_rate` run from 0 to 1, so `0.1766` means 17.66 percent of supply. The `price_change_percent` fields are already percentages.
- **Treat flags as numbers.** `renounced_mint`, `renounced_freeze_account` and `is_honeypot` come back as 1 or 0, while `is_wash_trading` is a boolean. Filter with the matching type.
- **Open token pages from the ranking.** Build `https://gmgn.ai/sol/token/` plus the `address` for each token you keep, and send that list to Batch with Extract.

## Frequently asked questions

### Is it legal to scrape GMGN?

GMGN shows market data about public on-chain tokens, such as prices, liquidity and holder counts, to every visitor, and collecting public market data for research is common practice. Wallet addresses are pseudonymous, but data that can be linked to a person falls under laws such as the GDPR and the CCPA, so collect only what you have a legitimate reason to use. Check GMGN's terms for your use case and ask your lawyer if you are unsure.

### Is there an official GMGN API?

GMGN offers data access to its own users on its own terms. Zenrows reads the same public feed the website uses, with one HTTP request and no GMGN account.

### What GMGN pages can I scrape?

The trending token feed, which returns the ranked list as JSON, and token pages at gmgn.ai/sol/token/<address> . The home view at gmgn.ai/?chain=sol works as a start page for Crawl.

### How do I scrape GMGN with Python?

Send a GET request to https://api.zenrows.com/v1/ with your API key, the GMGN feed URL and Adaptive Stealth Mode, as in the Python example above. Call response.json() and read data.rank : it is a list of dictionaries, one per token. The zenrows package on PyPI wraps the same request.

### How often can I refresh the GMGN ranking?

As often as your use needs: each request returns the ranking as it stands at that moment. Most teams poll on a fixed schedule from a cron job or a workflow tool and store each run with its own timestamp, which turns the feed into a time series.

### Does the scraper flag honeypots and rug risks?

It returns the flags GMGN publishes for each token: is_honeypot , renounced_mint , renounced_freeze_account , burn_status , rug_ratio , is_wash_trading , bundler_rate and the top 10 holder share. They are GMGN's own signals, passed through unchanged, and you decide how to weigh them.

### Can AI agents scrape GMGN with Zenrows?

Yes. Connect the Zenrows MCP server to Claude, Cursor, Codex or any MCP client, or give your agent the Zenrows CLI. Ask for the tokens and filters you want in plain language and the agent fetches the feed and filters it for you.

### Can I scrape GMGN on a schedule?

Yes. Create a scheduled Batch job with your GMGN URLs and the same settings as a single request, and Zenrows runs it on its side: every few hours, once a day, at set times on chosen days, or once at a future date. Each run keeps its own results, a webhook can notify your app when a run finishes, and the schedule can be paused or resumed at any time.

### Which integrations work with the GMGN scraper?

Zenrows works with n8n, Make, Zapier, Clay, Dify, LangChain, LlamaIndex, CrewAI and Mastra, plus the Python, Node.js and Go SDKs and any HTTP client. A scheduled n8n or Make scenario can fetch the ranking and write each token to a sheet, a database or a chat alert. See the integrations page for the full list.

### What format does the data come in?

The trending feed comes back as JSON in GMGN's own shape, with tokens in data.rank . Token pages with Extract return JSON with the structured record in parsed and the page in html . You can also ask for any page as Markdown or plain text.

All scrapers: https://www.zenrows.com/scrape. Start free: https://app.zenrows.com/register. Docs: https://docs.zenrows.com
