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.
Use it to:
Create callouts β a wallet calls a token, attributed to a verified Twitter/X account.
Read a wallet's history β paginate the callouts made by a single wallet.
Read a token's callouts β the cross-wallet callout feed for one token, including the highest-multiplier callout.
All endpoints are POST, accept and return application/json (UTF-8), and are authenticated with an AK/SK HMAC signature on every request. 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)
Response envelope
Every response is wrapped in a {code, message, data} envelope. Business data always lives under data β unwrap data; never read top-level fields directly.
{ "code": 0, "message": "", "data": { } }HTTP 200 + code = 0
Success. Business payload is in data. For write endpoints, whether the operation was accepted is data.success.
HTTP 4xx / 5xx
code (int) + message (string) describe the error. No data.
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:
Transport / auth / limits β HTTP status code (
400,401,429,500).Business rule β inside
data, the booleandata.success. Whenfalse, inspectdata.reject.reason.
Data types
Prices, market caps, multipliers, percentages, and token amounts are strings (e.g.
"0.5","2.3") 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_aton the/tokenfeed).ulidis the unique identifier of a callout.
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
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:
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/create.
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-Timestampdiffers 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
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.
Request rate (QPS)
Per your allocation (default β 10 QPS)
HTTP 429 rate limit exceeded
All endpoints
Callout 24h quota
Per your allocation
HTTP 429 ak daily quota exceeded
/create only
Read endpoints (
/get_record,/token) do not consume the callout 24h quota. They are still subject to the QPS limit.The 24h callout quota is distinct from the per-
twitter_idand per-wallet business limits, which surface as business rejects (data.success = false) rather thanHTTP 429β see reject reasons.
Endpoints
POST /create β Create a callout
Publish a callout: one on-chain wallet calling one token. The source platform is derived automatically from your ak β you do not pass it.
Request body
chain
string
β
Chain, e.g. sol / eth / bsc.
call_wallet
string
β
On-chain wallet address making the callout.
call_token
string
β
Token address being called.
twitter_id
string
β
Caller's Twitter/X rest_id. Numeric-only string (^[0-9]+$).
twitter_handle
string
@handle, used as a display fallback.
twitter_username
string
Display name, used as a display fallback.
call_thesis
string
Callout rationale text. Subject to content moderation.
callback_to_chain
string
Follow-callout: chain of the original post being followed.
callback_to_wallet
string
Follow-callout: wallet of the original post being followed.
callback_to_ulid
string
Follow-callout: ULID of the original post being followed.
βΉοΈ The three
callback_to_*fields describe a follow-callout (calling in response to another callout). Supply all three together, or none.
Success response (HTTP 200, data.success = true)
ulid is the unique identifier of the callout.
Business reject (HTTP 200, data.success = false)
The request was well-formed and authenticated, but a business rule blocked it:
β οΈ Branch on
reason(stable semantic string), never oncode(troubleshooting aid only).
Reject reasons
reason
code
Meaning
twitter_not_bound
40002401
The calling wallet has no bound Twitter/X account.
twitter_not_verified
40002406
The bound Twitter/X account has not passed verification.
content_violation
40002407
call_thesis hit the content-moderation filter.
content_audit_unavailable
40002408
Moderation service unavailable β fail-closed reject. Retry later.
holding_too_low
40002403
The wallet's holding of this token is below the threshold.
cooldown
40002404
Same wallet + same token is in a cooldown window. next_available_at (ms) and interval_minutes describe it.
twitter_daily_limit
40002409
This twitter_id exceeded its 24h callout count. next_available_at is the window reset time.
daily_limit
40002405
24h callout count exceeded. next_available_at is the window reset time.
reject fields
reason
string
Semantic reject reason (use this).
code
int
Numeric business code (troubleshooting only).
next_available_at
int64
For time-based rejects (cooldown, daily_limit, twitter_daily_limit): next allowed time, Unix ms.
interval_minutes
int64
For cooldown: length of the cooldown window in minutes.
βΉοΈ Token safety checks (honeypot, etc.) are currently disabled. They were previously a hard block, but new pools lacking safety data caused false rejections, so the hard block was removed in favor of a disclaimer approach. No safety-related
reasonis returned today β you do not need a handler branch for it. This may be reinstated later with separate notice.
Invalid parameters (HTTP 400)
Missing or non-numeric twitter_id returns the above; other missing required fields return a corresponding 400.
POST /get_record β Callouts by wallet
Return the callout history of a single wallet, newest first, with a cursor that pages toward older records. Read endpoint β does not consume the 24h quota.
Request body
chain
string
β
Chain.
call_wallet
string
β
Wallet address to query.
limit
int
Page size. Max 50.
page_token
string
Pagination cursor (next_page_token from the previous page). Empty for the first page.
Success response
records[] fields
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 (e.g. "2.3").
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.
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.
βΉοΈ Unlike
/token,/get_recordreflects the real callout source percall_wallet. If you need to distinguish which platform a callout came from, use this endpoint.
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), and a pagination cursor. Read endpoint β does not consume the 24h quota.
Request body
chain
string
β
Chain.
call_token
string
β
Token address.
cursor
string
Pagination cursor (base64). Empty for the first page.
limit
int
Page size.
Success response
messages[] fields
id
string
Message identifier.
content
string
Callout thesis / text.
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.
created_at
string
ISO-8601 timestamp of the callout.
source
string / null
Callout source β see note below.
multiplier
string
Multiplier vs. callout price.
ulid
string
Callout unique identifier.
top_message β the highest-multiplier callout for this token in the last 30 days. Returned only on the first page (empty cursor). If there is none, the field is omitted.
Pagination
has_more(bool) is the authoritative signal for whether to keep paging.next_cursoris returned only whenhas_moreistrue. When there are no more pages the field is omitted entirely (not an empty string ornull).
β οΈ Page on
has_more, not on the presence ofnext_cursor.βΉοΈ On
/token,sourceis alwaysgmgnβ this aggregated token-page view does not pass through third-party source identifiers. To distinguish callouts by originating platform, use/get_record, which reflects the real source percall_wallet.
HTTP status codes
200
Request handled. For writes, inspect data.success.
400
Invalid parameters (missing/malformed required field).
401
Signature authentication failed. See Authentication failures.
429
Rate limit or 24h quota exceeded. See Rate limits.
500
Internal error. Safe to retry with backoff.
OpenAPI 3.0 specification
The complete OAS 3.0 definition below can be imported directly into Swagger UI, Redoc, or Postman.
βΉοΈ The
X-Signaturevalue must be computed per request β it cannot be a static value in Swagger/Postman. Use a pre-request script to build the signature overak + timestamp + method + path + rawQuery + body.
Last updated