For the complete documentation index, see llms.txt. This page is also available as Markdown.

GMGN Callout OpenAPI

The GMGN Callout OpenAPI lets approved partners programmatically publish and read on-chain "callouts" — a signal from a wallet that it is calling a specific token, optionally with a thesis and a linked Twitter/X identity.

Application Form: https://docs.google.com/forms/d/e/1FAIpQLScRnqI0PSQBEewJnF3JnfRSm50PylZRcIAfE7bl96Yp7RCQCg/viewform?usp=dialog

All endpoints are POST, accept and return application/json (UTF-8), and are authenticated with an AK/SK HMAC signature on every request. Rate limits are enforced per ak. Your ak / sk credentials are issued by GMGN.

Base URL

https://papi.gmgn.ai/callout/openapi/v1

Content-Type

application/json (UTF-8)

Auth

AK/SK HMAC-SHA256 signature (headers on every request)

Where to start

Endpoint
Mode
What it gives you

/global

Read-only

Every callout across all chains and wallets, newest first. The simplest way to integrate — no filters, no parameters beyond a cursor.

/token

Read-only

One token's cross-wallet feed, plus its Best Callout and paid pinned declaration.

/get_record

Read-only

One wallet's callout history, and the only endpoint that reports the true callout source.

/create

Write

Publish a callout, or a Callback onto someone else's call.

If you only want to consume the firehose — a community bot, a feed, a dashboard — you need /global and nothing else.


POST /global — Global callout stream (read-only)

The global callout stream: every callout across all chains and all wallets, in strict reverse-chronological order (newest first), with a cursor that pages toward older records. Built for read-only community, bot, and feed integrations.

POST https://papi.gmgn.ai/callout/openapi/v1/global

Four fixed constraints

These are fixed server-side and cannot be changed by any request parameter:

#
Constraint
Detail

1

Last 7 days only

Once paging reaches the 7-day boundary, next_page_token stops being returned and pagination terminates naturally.

2

1 QPS

Per ak, counted independently from the other endpoints' shared ~10 QPS pool. See Rate limits.

3

No filtering

The server ignores any chains / only_kol / only_declaration / limit you send. It always returns the full cross-chain stream.

4

100 records per page

Fixed page size.

Request body

Field
Type
Required
Description

page_token

string

Pagination cursor (next_page_token from the previous page). Omit or leave empty for the first page.

ℹ️ Every field other than page_token is ignored — the global stream accepts no filters. An empty body or a malformed body is treated as a first-page request and returns 200, not 400.

Success response

records[] fields

Field
Type
Description

chain

string

Chain.

call_wallet

string

Wallet that made the callout.

call_token

string

Token address called.

call_price

string

Token price at callout time.

call_mc

string

Market cap at callout time.

ulid

string

Callout unique identifier.

create_time

int64

Callout time, Unix milliseconds.

token_symbol

string

Token symbol.

token_logo

string

Token logo URL.

multiplier

string

Current multiplier vs. callout price.

twitter_username

string

Caller display name.

twitter_handle

string

Caller @handle.

holding_percentage

string

Caller's holding percentage of the token.

source

string

Callout source — GMGN-native callouts report the device (web / android / ios); third-party platform callouts report that platform's identifier.

is_kol

bool

Whether the calling wallet is a GMGN-tagged KOL wallet (KOLs who linked their own Twitter/X; public data). Always returned as true or false.

is_declaration

bool

Whether this is a paid declaration callout. omitempty — present only when true; a missing field means false.

Ordering and pagination

  • Records are in strict descending order by create_time (then ulid), merged across chains — paging never duplicates or skips a record.

  • Pass page_token = the previous response's next_page_token to fetch the next (older) page.

  • An empty or absent next_page_token means you have reached the 7-day boundary or exhausted the data — stop paging.

  • Other omitempty fields (e.g. callback_*) are absent when they have no value.

ℹ️ This endpoint returns only the boolean is_declaration flag. It does not return paid-declaration details such as amount_usd or the declaration's start time. Contact us if you need those.


Response envelope

Every endpoint returns a {code, message, data} envelope. Always unwrap data — do not read top-level fields as business data.

  • HTTP 200 + code = 0 — Request succeeded. The business payload is under data.

  • HTTP 4xx / 5xx — code (int) and message (string) describe the error. No data is returned.

Two layers of outcome for writes

For POST /create, a transport-level HTTP 200 does not mean the callout was accepted. There are two distinct layers:

  1. Transport / auth / limits — HTTP status code (400, 401, 429, 500).

  2. Business rule — inside data, the boolean data.success. When false, inspect data.reject.reason.

Data types

  • Prices, market caps, multipliers, percentages, and paid amounts are strings (e.g. "0.5", "3.2") to preserve precision. Parse with a decimal-safe library, not native floats.

  • Timestamps are Unix milliseconds (int64) unless a field is explicitly an ISO-8601 string (e.g. created_at on the /token feed).

  • ulid is the unique identifier of a callout.

  • Fields marked omitempty are absent from the JSON when empty — do not assume a key exists.


Authentication

Every request must be signed with your AK/SK credentials using HMAC-SHA256. Keep the sk server-side — never ship it in a client app or browser.

Required headers

Header
Description

X-Ak

Your issued access key.

X-Timestamp

Current time as a Unix millisecond timestamp.

X-Signature

Lowercase hex HMAC-SHA256 of the payload below.

Signature payload

Concatenate these fields in order, with no separators:

Field
Description

ak

Same value as X-Ak.

timestamp

Same value as X-Timestamp (millisecond string).

method

Uppercase HTTP method, e.g. POST.

path

Request path including the API prefix, excluding host and query, e.g. /callout/openapi/v1/global.

rawQuery

URL query string (empty string for these POST endpoints).

body

Raw request body — must match the bytes actually sent exactly. Empty string if there is no body.

⚠️ Timestamp window: ±30 seconds. If X-Timestamp differs from server time by more than 30s the request is rejected. Keep your client clock synced (NTP).

ℹ️ Because the signature covers the raw body bytes, sign the exact serialized JSON string you send. Do not re-serialize, pretty-print, or reorder keys between signing and sending.

Signing examples

Go
Python
Node.js

Authentication failures (HTTP 401)

message

Meaning

missing auth header

One of X-Ak / X-Timestamp / X-Signature is absent.

invalid timestamp

X-Timestamp is malformed or outside the ±30s window.

invalid ak

The access key is not recognized.

invalid signature

The computed signature does not match.

api not allowed

This ak is not permitted to call this endpoint.

ip not allowed

The request originated from a non-allowlisted IP.


Rate limits

Limits are enforced per ak.

Limit
Quota
Over-limit response
Applies to

Request rate (QPS)

Per your allocation (default ≈ 10 QPS)

HTTP 429 rate limit exceeded

/create, /get_record, /token

Global stream rate (QPS)

1 QPS (strict, per ak)

HTTP 429 rate limit exceeded

/global only

Callout 24h quota

Per your allocation

HTTP 429 ak daily quota exceeded

/create only

  • The read endpoints (/global, /get_record, /token) do not consume the callout 24h quota.

  • /global has its own 1 QPS bucket, counted separately from the ~10 QPS pool shared by the other endpoints. It is also restricted to the last 7 days and supports no filtering — see the four fixed constraints.

  • The 24h callout quota is distinct from the per-twitter_id and per-wallet business limits, which surface as business rejects (data.success = false) rather than HTTP 429 — see reject reasons.


POST /token — Callouts by token

Return the cross-wallet callout feed for one token: all callouts on that token, the highest-multiplier callout (top_message), the paid pinned declaration (vip_message), and a pagination cursor.

Request body

Field
Type
Required
Description

chain

string

✅

Chain.

call_token

string

✅

Token address.

cursor

string

Pagination cursor. Empty for the first page.

limit

int

Page size, max 50. Values <= 0 or > 50 are capped at 50.

⚠️ Note the asymmetry with /get_record: this endpoint caps an out-of-range limit at 50, whereas /get_record falls back to 20.

Success response

messages[] fields

Field
Type
Description

id

string

Message identifier.

content

string

Callout thesis / text (source language).

display_content

string

Translated text. Always empty on this API — the OpenAPI path forces an empty app_lang, so only the source content is returned.

media_url

string / null

Attached media, if any.

username

string

Caller handle.

display_name

string

Caller display name.

profile_image_url

string / null

Caller avatar URL.

wallet_address

string

Caller wallet address.

user_twitter_url

string

Caller Twitter/X profile URL.

follower_count

int64

Caller follower count.

like_count

int64

Like count. Currently always 0 (retained for structural compatibility after the pump sunset).

reply_count

int64

Reply count. Currently always 0 (same reason).

created_at

string

ISO-8601 timestamp of the callout.

source

string / null

Always gmgn on this endpoint — see note below.

multiplier

string

Multiplier vs. callout price.

ulid

string

Callout unique identifier.

callback_count

int

How many times this post has been called back.

callback_to_ulid

string

ULID of the original post this one calls back to.

callback_to_chain

string

Chain of that original post.

callback_to_wallet

string

Wallet of that original post.

Callbacks

callback_count is present on both original posts and callback posts — it counts how many callbacks a post received. The callback_to_* trio points at the original post being called back; when all three are empty, the record is an original post, not a callback. All are omitempty.

top_message — Best Callout

The highest-multiplier callout for this token in the last 30 days (compared as decimals).

⚠️ Returned on every page, not just the first — the current implementation does not distinguish first page from subsequent pages. It is absent when there are no callouts in the 30-day window.

vip_message — paid pinned declaration

The paid pinned declaration, assembled from callout-declaration records with success recharge status. Same structure as a messages[] item, plus:

Field
Type
Description

amount_usd

string

The paid tier amount. Filled only on vip_message — never on top_message.

  • omitempty — absent when there is no success record.

  • Sits alongside top_message; both can appear at the same time.

ℹ️ vip_message.amount_usd is paid-tier information and is passed through to partners as-is by this endpoint.

declaration_level

The token's current recharge tier. This is a top-level field describing the token, not a property of any single declaration. In phase one it is the default value "199", reserved for future tier expansion and bidding floor prices.

Pagination

  • has_more (bool) is the authoritative signal for whether to keep paging.

  • next_cursor is returned only when has_more is true. When there are no more pages the field is omitted entirely (not an empty string or null).

⚠️ Page on has_more, not on the presence of next_cursor.

ℹ️ On /token, source is always gmgn — this aggregated token-page view does not pass through third-party source identifiers. To distinguish callouts by originating platform, use /get_record.


POST /get_record — Callouts by wallet

Return the callout history of a single wallet, newest first, with a cursor that pages toward older records.

Request body

Field
Type
Required
Description

chain

string

✅

Chain.

call_wallet

string

✅

Wallet address to query.

limit

int

Page size. Must be between 1 and 50.

page_token

string

Pagination cursor (next_page_token from the previous page). Empty for the first page.

⚠️ limit out of range falls back to the default 20, not to 50. Sending limit: 100 returns 20 records, not 50. The same is true for limit <= 0. To get 50 per page you must send exactly 50. (This differs from /token, which caps at 50.)

Success response

records[] fields

Field
Type
Description

chain

string

Chain.

call_wallet

string

Wallet that made the callout.

call_token

string

Token address called.

call_price

string

Token price at callout time.

call_mc

string

Market cap at callout time.

ulid

string

Callout unique identifier.

multiplier

string

Current multiplier vs. callout price.

token_symbol

string

Token symbol.

token_logo

string

Token logo URL.

twitter_username

string

Caller display name.

holding_percentage

string

Caller's holding percentage of the token.

source

string

True callout source — see below.

callback_count

int

How many times this post has been called back.

callback_to_ulid / callback_to_chain / callback_to_wallet

string

The original post this one calls back to. omitempty.

source — the only endpoint that reports the real platform

source reports the true origin of the callout: GMGN-native callouts report the device name (web / android / ios), and third-party platform callouts report that platform's identifier.

ℹ️ This endpoint resolves source per call_wallet, so you can use it to distinguish platforms. /token always reports gmgn and does not pass through third-party identifiers.

Callbacks

Same semantics as /token — see Callbacks. All callback_* fields are omitempty.

Pagination

Pass page_token = the previous response's next_page_token to fetch the next (older) page. An empty next_page_token means there are no older records.


OpenAPI 3.0 specification

The complete OAS 3.0 definition below can be imported directly into Swagger UI, Redoc, or Postman.

ℹ️ The X-Signature value must be computed per request — it cannot be a static value in Swagger/Postman. Use a pre-request script to build the signature over ak + timestamp + method + path + rawQuery + body.

Last updated