/v1/docs
This documentation (JSON). Browsers (Accept: text/html) are redirected to the human-readable docs.
Request
https://api.xrpl.to/v1/docscurl 'https://api.xrpl.to/v1/docs'
Response
https://api.xrpl.to/v1/docs{ "title": "XRPL.to API", "version": "1.20", "baseUrl": "https://api.xrpl.to/v1", "baseUrlNotes": "https://api.xrpl.to/v1 is the canonical base. https://api.xrpl.to/api serves the identical API (internal alias) — use /v1 in new integrations.", "openapi": "https://api.xrpl.to/v1/openapi.json", "openapiNotes": "Full OpenAPI 3.1 spec (270+ paths with parameter/response schemas) — use it for codegen, Postman, and LLM tooling.", "humanDocs": "https://xrpl.to/docs", "quickStart": { "example": "curl \"https://api.xrpl.to/v1/tokens?limit=10\"", "authenticatedExample": "curl -H \"X-Api-Key: YOUR_KEY\" \"https://api.xrpl.to/v1/tokens?limit=10\"", "websocket": "wss://api.xrpl.to/ws/sync/", "notes": "Quote URLs in shells (zsh globs on \"?\"). No key needed to start — see rateLimits.anonymous. Get a key: POST /v1/keys (wallet signature) or via https://xrpl.to/docs." }, "authentication": { "apiKey": { "description": "Pass your API key via header", "header": "X-Api-Key: YOUR_API_KEY", "gettingAKey": "Create one with POST /v1/keys (requires a wallet signature — see the keys section) or through the dashboard at https://xrpl.to/dashboard. Free tier: 1 active key, 1M credits/mo.", "notes": "Most read endpoints work without a key (anonymous tier). API keys provide higher rate limits and credit allocations." }, "walletSignature": { "description": "Required for key management and account operations", "headers": { "X-Wallet": "Your XRPL r-address", "X-Signature": "Hex signature of message \"{wallet}:{timestamp}\"", "X-Timestamp": "Unix milliseconds timestamp (5 min validity window)", "X-Public-Key": "Hex public key (always required for /user and /watchlist signed routes; optional for /keys routes after first on-ledger transaction)" } }, "userAgent": "Requests with generic programmatic User-Agent strings (e.g. Python-urllib) may be challenged by the CDN/WAF with a non-JSON 403 before reaching the API. Always send a descriptive User-Agent identifying your app (e.g. \"myapp/1.0\")." }, "usagePolicy": { "appliesTo": "Every caller — no key, Free, and every paid tier alike.", "attribution": "REQUIRED. Any app, website, bot, or dashboard that displays xrpl.to data must show a visible, clickable credit to xrpl.to on the same screen as that data — not buried in an about page. Use: <a href=\"https://xrpl.to\" target=\"_blank\" rel=\"noopener\">Data by xrpl.to</a>", "redistribution": "Storing our data and re-serving it from your own API, dataset, or public dashboard requires written permission first. Email hello@xrpl.to — the answer is usually yes, we just need to know who is doing it.", "indexers": "Use the paginated list endpoints instead of looping one item at a time, cache what you fetch, and honour Retry-After on a 429 — a repeated 429 means back off, not retry. Get a key rather than running anonymous so we can raise your limits instead of blocking you.", "partner": "The invitation-only Partner tier (100 req/sec, 20M credits/mo, direct support) is free for integrations that credit us properly. Email hello@xrpl.to or DM @xrplto on X.", "contact": "hello@xrpl.to" }, "rateLimits": { "description": "Four independent layers apply to every request; the strictest one wins. All 429 responses carry Retry-After plus X-RateLimit-Limit/-Remaining/-Reset headers and a JSON body with retryAfter.", "layers": { "ipBurst": "All clients: 100 requests per 2s per IP (DDoS backstop). 429 with Retry-After: 2.", "perSecond": "Sustained rate enforced over a 10s window, plus a hard 1-second burst cap. Anonymous: 2/sec burst, 30/min sustained, per IP. Free: 10/sec sustained with 20/sec bursts (shared per IP across keys). Keyed tiers per key — developer 50/sec (burst 100), partner 100/sec (burst 200), business 200/sec (burst 300), professional 500/sec (burst 750).", "perMinute": "Anonymous and free: 30 req/min and 600 req/min per IP respectively.", "perEndpoint": "Expensive endpoints have their own request windows, matched by path prefix (so /tokens and /tokens/slugs share one bucket). Base limits are per 60s and scale by tier multiplier: anonymous 0.25x, free 1x, developer 3x, partner 5x, business 10x, professional 15x, enterprise uncapped. Examples at anonymous tier: /tokens 5/min, /search 7/min, /amm 7/min, /account/tx 5/min. Some endpoints pin per-tier …" }, "daily": "Anonymous: 333 requests/day per IP. Free: 33K/day per IP. Keyed tiers per key: developer 400K/day, partner 1M/day, business 4M/day, professional 8M/day. Successful responses include X-RateLimit-Daily-Remaining where a daily cap applies.", "headers": "Successful responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (seconds until the window resets). For anonymous clients these reflect the per-minute window; for keyed clients the per-second window. Credit-metered keys also get X-Credits-Used / X-Credits-Remaining.", "anonymous": "2 req/sec burst, 30 req/min, 333/day (no key) + 0.25x endpoint windows", "free": "10 req/sec (burst 20, 600/min), 33K req/day per IP, 1M credits/mo (free API key)", "developer": "50 req/sec (burst 100), 5 tx/sec, 400K req/day, 10M credits/mo, 3x endpoint windows", "partner": "100 req/sec (burst 200), 10 tx/sec, 1M req/day, 20M credits/mo, 5x endpoint windows (invitation-only, for integration partners)", "business": "200 req/sec (burst 300), 50 tx/sec, 4M req/day, 100M credits/mo, 10x endpoint windows", "professional": "500 req/sec (burst 750), 100 tx/sec, 8M req/day, 200M credits/mo, 15x endpoint windows", "notes": "Each endpoint has a credit cost (0-10 credits per call). Check /keys/costs for details. WebSocket messages cost 0.1 credits each. Scam-blocklist reads (/scams/*, /nft/scam) are never rate-limited or capped." }, "tokenIdFormat": { "description": "All {id} parameters accept any of these formats:", "formats": { "md5": "32-char hex hash", "slug": "issuer-currency (e.g. rhcyBrowwApgNonehKBj8Po5z4gTyRknaU-VGB)", "issuer_currency": "issuer_currencyHex (40-char hex currency, underscore separator)", "mpt": "mpt-<48-char mptIssuanceID> (MPT slug form)", "xrp": "Native XRP: use the literal \"XRP\" (or its canonical md5 84e5efeb89c4eae8f68188982dc290d8). Works everywhere a token {id} is accepted, e.g. /token/XRP, /stats/rates?token1=XRP&token2={md5}, /ohlc/XRP." } }, "conventions": { "took": "Server-side processing time: integer MILLISECONDS as a JSON number, on every endpoint. Excludes network transfer.", "countAndTotal": "One meaning everywhere: count = rows in THIS response; total (also pagination.total / meta.total) = rows matching the query pre-pagination. Exception: on single-resource + metrics responses (/stats, /stats/rates, /token/{id}), the envelope's total is the count of all indexed tokens — a platform stat, not pagination. A few older endpoints use length; its meaning is stated per endpoint.", "clamping": "Out-of-range numeric params are clamped, not rejected (limit above max -> max, negative offset -> 0, non-numeric -> default); the effective value is echoed in the response. Invalid enum values fall back to the documented default (e.g. an unknown range/interval/sort). An unknown tag returns 200 with 0 rows and empty tagName — check tagName to distinguish a typo from genuinely no data.", "numericStrings": "Very-high-precision amounts (amount, supply, usd, exch on some endpoints, sparkline prices) are serialized as STRINGS on purpose — XRPL token amounts exceed IEEE-754 float precision. Parse with a decimal library if you need exact math.", "timestamps": "Unix milliseconds (13 digits) unless a field is explicitly documented otherwise.", "attribution": "Successful responses on the tiers that pay nothing (anonymous, free, partner) carry an `attribution` string right after `success`, restating the requirement in usagePolicy. It is informational — safe to ignore in code, but not optional to comply with. Paid tiers omit it and owe the same attribution." }, "tokenFields": { "identity": { "md5": "canonical token id — md5(issuer + \"_\" + currency)", "issuer": "issuer r-address (\"XRPL\" for native XRP)", "currency": "3-char code or 40-char hex currency", "name": "display ticker/name", "user": "issuer display name", "slug": "URL slug (issuer-currency)", "tokenType": "trustline|lp|mpt|xls14|demurrage|nonstandard", "origin": "launchpad/source platform (FirstLedger, XPMarket, LedgerMeme, ...)", "tags": "category tags (see /tags)", "dateon": "listing time (unix ms)" }, "price": { "exch": "current price in XRP (string, precision-preserving)", "usd": "current price in USD (string)", "dom": "market dominance % of total XRPL token marketcap", "pro5m": "% price change, last 5 minutes", "pro1h": "% 1h", "pro24h": "% 24h", "pro7d": "% 7d", "pro30d": "% 30d", "maxMin24h": "[max, min] price over 24h — MAX FIRST", "athDistance": "% below all-time high" }, "market": { "marketcap": "live marketcap in XRP (number; price x circulating supply, computed server-side — do not recompute)", "vol24hxrp": "24h volume in XRP", "vol24htx": "24h trade count", "vol24h": "24h token-side volume", "amount": "total issued supply (string)", "supply": "circulating supply (string)", "tvl": "AMM total value locked (XRP)", "holders": "trustline holders with balance", "holders24h": "24h holder-count CHANGE (negative = net loss)", "trustlines": "total trustlines", "uniqueTraders24h": "distinct traders in 24h", "buyerPressure": "buy/sell volume ratio (24h); 1.0 = balanced, above 1 = net buying", "buy24hxrp": "24h BUY volume in XRP", "sell24hxrp": "24h SELL volume in XRP", "buy24htx": "24h buy trade count", "sell24htx": "24h sell trade count", "vol24hAMM": "24h volume filled by AMM pools (XRP)", "vol24hOrderbook": "24h volume filled on the order book (XRP)", "liquidityRatio": "24h volume / marketcap (ratio, not a percent)", "depthPlus2": "XRP that can be BOUGHT against the AMM pool before its price rises 2%", "depthMinus2": "XRP received SELLING against the AMM pool before its price falls 2%", "tvlChange24h": "TVL change vs ~24h ago in XRP (from hourly pool snapshots; absent = no 24h-old baseline)", "vol6hxrp": "6h traded volume in XRP (hourly recompute)", "vol7dxrp": "7d traded volume in XRP (hourly recompute)", "gini": "holder-balance Gini coefficient 0-1 (1 = max inequality; basis-independent)", "hhi": "Herfindahl concentration index, Σ(holding%)² 0-10000, on total supply", "tradingFee": "AMM pool trading fee in rippled TradingFee units: 1/100000 (1000 = 1%)" }, "signals": { "rsi15m_90d": "RSI oscillator per timeframe (rsi15m, rsi1h, rsi4h, rsi24h, rsi7d, rsi30d, rsi90d)", "trendingScore": "decaying pageview+activity trend score", "assessmentScore": "raw risk/quality score (see /token/review for the graded verdict)", "creatorHoldingPercent": "% of supply held by the creator wallet", "top10": "% of supply held by the top 10 holders", "lpBurnedPercent": "% of AMM LP tokens burned", "isOMCF": "\"yes\" = listed/indexed token (On Main Chart Filter); tokens without it are unlisted", "verified": "verification tier: 1 (company) | 2 | 4 (paid); absent/false = unverified", "kyc": "issuer passed Xaman wallet KYC", "xVerified": "linked X account is verified", "views24h": "site pageviews (24h)" }, "notes": "The full object carries additional self-describing metric variants (7d/30d windows, per-fiat conversions). lightweight=true on /tokens strips to the ~50 essential fields listed here." }, "tokens": [ { "method": "GET", "path": "/tokens", "description": "List all tokens with metrics", "params": { "limit": "int (max 100; default 100, or 50 with tag/filter/filterNe, 20 with sort=assessmentScore|pro5m|trendingScore)", "offset": "int (default 0)", "sort": "token field name: vol24hxrp|marketcap|pro5m|pro1h|pro24h|pro7d|exch|holders|tvl|trendingScore|assessmentScore|dateon (unknown field = no-op)", "order": "asc|desc (default: desc)", "tag": "filter by tag (see /tags, case-insensitive)", "filter": "text search on token name", "watchlist": "watchlist owner account (r-address) — filters to that account's watchlist tokens", "show_new": "bool - only tokens created in the last 7 days", "show_slug": "bool - only tokens whose slug equals their md5", "show_date": "bool - only tokens with missing/unknown date", "tags": "yes - include tags array", "token_type": "trustline|lp|mpt|xls14|demurrage|nonstandard (invalid value = no filter, echoed back as token_type: null)", "skip_metrics": "bool - skip the global metrics envelope (exch/H24/global) — combine with lightweight for the smallest payload", "lightweight": "bool - strip each token to ~50 essential fields (~77% smaller per token; see tokenFields)", "filterNe": "text - exclude matching tokens (negative filter)" }, "response": "{ success, took (ms), total (tokens matching the query, pre-pagination), count (tokens in this response), start, limit, tagName, sortBy, sortType, tokens[], exch, H24, global (metrics omitted when skip_metrics=true) }" }, { "method": "GET", "path": "/tokens/slugs", "description": "All token slugs", "response": "{ success, count (rows returned), total (all matching), truncated, slugs[] }" }, { "method": "GET", "path": "/token/{id}", "description": "Single token by id (see tokenFields for the token object dictionary)", "params": { "desc": "yes - include description", "skip_metrics": "bool - omit the global metrics envelope (exch/total/H24/global)" }, "response": "{ success, took, total, exch, H24, global, token }" }, { "method": "POST", "path": "/search", "body": "{ search, offset?, limit? }", "description": "Search tokens, NFTs, collections, and accounts. limit max 100; offset clamped so offset+limit <= 100", "response": "{ success, took, tokens[], collections[] (up to 20, best match first; tolerates one typo, missing spaces, initials like \"baxc\" and extra words like \"nft\" or \"the\"), nfts[] (up to 20; identical names in one collection collapse to one row with editions: N; \"name #N\" queries resolve item N of the named collection), order (result groups strongest match first, e.g. [\"nfts\",\"collections\",\"tokens\"]), acc…" }, { "method": "GET", "path": "/tags", "description": "List all token tags", "response": "{ success, took, exch, H24, global, tags }" } ], "charts": [ { "method": "GET", "path": "/ohlc/{id}", "description": "OHLC candlestick data", "params": { "range": "1D|5D|7D|1M|3M|1Y|5Y|ALL", "interval": "1m|5m|15m|30m|1h|2h|4h|1d|1w", "vs_currency": "XRP|USD|EUR|JPY|CNH (default: XRP)", "resolution": "int (minutes), or D|W", "cb": "int (candle bar count, max 5000)", "invert": "bool" }, "response": "{ success, took, length, format, resolution, interval, interval_seconds, vs_currency, inverted, base_interval, preAgg?, ohlc: [[time, open, high, low, close, volume, ...]] }" }, { "method": "GET", "path": "/sparkline/{id}", "description": "Price sparkline", "params": { "period": "24h|7d (default: 7d)", "vs_currency": "XRP|USD (default: XRP)", "lightweight": "bool - sample data points", "max_points": "int (default: 20, range 2-500; only applies when lightweight=true)", "pro24h": "float - override percentChange/chartColor when period=24h", "pro7d": "float - override when period=7d" }, "response": "{ success, chartColor, period, percentChange, lightweight, vsCurrency, data: { prices[], timestamps[], max, min } }" }, { "method": "GET", "path": "/holders/info/{id}", "description": "Holder concentration (top10/20/50/100 %)", "response": "{ success, took, richInfo: { time, length, holders, top10, top20, top50, top100, active24H } }" }, { "method": "GET", "path": "/holders/graph/{id}", "description": "Holder count history", "params": { "range": "1D|7D|1M|3M|1Y|5Y|ALL (default: 7D)" }, "response": "{ success, took, length, history[] }" }, { "method": "GET", "path": "/holders/list/{id}", "description": "Paginated holder richlist with acquisition tracking", "params": { "offset": "int", "limit": "int (default: 20, max 200)", "freeze": "bool - only frozen trustlines", "sort": "balance|value|holding|percent|change24h|pnl (value/percent are balance/holding aliases; default: balance desc)", "order": "asc|desc", "search": "account address (min 3 chars)", "minBalance": "float - min balance (token units)", "maxBalance": "float - max balance (token units)" }, "response": "{ success, took, summary: { top10Hold, top20Hold, top50Hold, top100Hold, frozen }, length (total holders; filtered count when search/minBalance/maxBalance set), richList[]: { account, balance, holding, rank, freeze, frozenByIssuer?, isCreator, xrpBalance, lastActive, name, domain, funder, tradedPct?, tradeCount?, source?, acquisition?, isAMM?, pnl? (realized+residual XRP), roi?, unrealized?, bough…" } ], "trading": [ { "method": "GET", "path": "/history", "description": "Trade history by token, account, or both", "params": { "md5": "token id (optional if account provided)", "account": "r-address", "limit": "int (max 1000)", "offset": "int", "start_time": "unix ms", "end_time": "unix ms", "type": "trades|liquidity|all (default: trades)", "liquidity_type": "create|deposit|withdraw", "pair_type": "xrp|token", "xrp_only": "bool", "xrp_amount": "float (min XRP threshold)", "cursor": "int", "direction": "asc|desc (default: desc)" }, "response": "{ success, took, data[], meta: { total, offset, limit, direction, nextCursor, hasMore, truncated?, timeRange } }", "notes": "Offset pagination capped at 100k rows (meta.truncated: true, total capped to servable window; use cursor for deeper history). Trades carry sourceTag (numeric, on-chain SourceTag) and/or platform (canonical name for memo-identified platforms, e.g. SPYDEX)" }, { "method": "GET", "path": "/amm", "description": "List AMM pools", "params": { "sort": "fees|apy|liquidity|volume|created", "status": "active|all", "limit": "int (max 100)", "offset": "int", "token": "token id", "currency": "currency code filter", "issuer": "issuer address filter" }, "response": "{ success, took, summary, offset, limit, total (matching pools), count (pools in this response), totalPages, pools[] }" }, { "method": "GET", "path": "/amm/info", "description": "Live AMM pool info", "params": { "amm_account": "AMM account address", "asset": "XRP | token id", "asset2": "XRP | token id" } }, { "method": "GET", "path": "/amm/liquidity-chart", "description": "Historical TVL chart data", "params": { "token": "token id", "token2": "token id", "ammAccount": "address", "period": "1d|5d|1w|1m|3m|6m|1y|5y|all", "poolType": "xrp|token|all" } }, { "method": "GET", "path": "/pairs", "params": { "md5": "token id (required)" }, "description": "Trading pairs for a token", "response": "{ success, took, count, limit: 100, truncated, pairs[] }" } ], "account": [ { "method": "GET", "path": "/account/balance/{account}", "description": "XRP balance with reserves", "params": { "simple": "bool - minimal response", "rank": "bool - include rank (slow)" }, "response": "{ balance, total, balanceDrops, spendableDrops, ownerCount, sequence, flags, reserve, reserveDrops, name, inception, parent, rank? }" }, { "method": "POST", "path": "/account/balance", "body": "{ accounts[] }", "description": "Batch balance lookup (max 100)", "response": "{ success, took, count, data[]: { account, balance (spendable after reserves), total } }" }, { "method": "GET", "path": "/account/balance/pair/{account}", "params": { "curr1": "currency", "issuer1": "issuer", "curr2": "currency", "issuer2": "issuer" }, "description": "Token pair balances" }, { "method": "GET", "path": "/account/offers/{account}", "params": { "pair": "pair hash", "md5": "token id (filters offers to that token)", "offset": "int (snaps down to a limit-multiple; effective offset echoed)", "limit": "int (1-50, default 10; out-of-range resets to 10)" }, "description": "Open DEX offers", "response": "{ success, took, offset, limit, total, offers[] }" }, { "method": "GET", "path": "/account/tx/{account}", "description": "Full transaction history", "params": { "limit": "int (1-200, default 200)", "marker": "JSON string (URL-encoded), e.g. {\"ledger\":N,\"seq\":M}", "types": "comma-separated TransactionTypes", "forward": "bool (default: false)", "ledgerMin": "int - ledger index lower bound", "ledgerMax": "int - ledger index upper bound" }, "response": "{ success, took, count, hasMore, marker, txs[] }", "notes": "Own rate window: 20 requests/min per IP on Free, 5/min without a key, more on paid tiers (see rateLimits.layers.perEndpoint)" } ], "ledger": [ { "method": "GET", "path": "/ledger", "description": "Current validated ledger info", "response": "{ ledger_index, ledger_hash, close_time (ms), close_time_human, parent_hash, total_coins, txn_count, validated, reserve_base_drops, reserve_inc_drops }", "notes": "reserve_base_drops / reserve_inc_drops are the validator-voted account reserve settings, in drops. reserve_inc_drops is the Fee an AccountDelete or AMMCreate MUST carry (one owner reserve) — read it here, never hardcode it: validators can vote the increment, and a stale constant means telINSUF_FEE_P if it rose or a silent overpayment if it fell." }, { "method": "GET", "path": "/ledger/{index}", "description": "Ledger by index with transactions", "params": { "index": "ledger index or: validated|closed|current", "transactions": "bool (default: true)", "expand": "bool (default: false)" } }, { "method": "GET", "path": "/ledger/entry", "description": "Fetch specific ledger object", "params": { "index": "entry index", "account_root": "address", "offer": "JSON { account, seq }", "amm": "JSON { asset, asset2 }", "check": "ID", "escrow": "JSON { owner, seq }", "directory": "JSON { dir_root | owner, sub_index? } or plain 64-hex index", "payment_channel": "ID", "deposit_preauth": "JSON { owner, authorized }", "ticket": "JSON { account, ticket_seq }", "nft_page": "index" }, "notes": "Malformed JSON in object params returns 400" }, { "method": "GET", "path": "/tx/{hash}", "description": "Transaction by hash (64-char hex)" }, { "method": "GET", "path": "/ledger/at", "params": { "time": "unix ms or ISO date (required)" }, "description": "Resolve a datetime to the last ledger closed at or before it (binary search)", "response": "{ ledger_index, close_time, clampedToHead?, clampedToGenesis? }" } ], "submit": [ { "method": "POST", "path": "/submit", "description": "Submit signed transaction", "body": "{ tx_blob, fail_hard? }", "constraints": "Max tx_blob: 131KB hex. Per-tier rate limit: Free 1/sec, Developer 5/sec, Partner 10/sec, Business 50/sec, Professional 100/sec.", "response": "{ success, took, engine_result, engine_result_code, engine_result_message, tx_json, hash, accepted, applied, broadcast, kept, queued, account_sequence_available, account_sequence_next, validated_ledger_index, outcome? }", "notes": "Duplicate tx_blob within 30s returns 409" }, { "method": "POST", "path": "/submit/preview", "body": "{ tx_json } or { tx_blob }", "description": "Dry-run transaction preview (400 on invalid tx input); sender_after = simulated sender position {balance, reserve, spendable}, null when no sender AccountRoot change", "response": "{ success, took, engine_result, engine_result_message, meta, tx_json, sender_after }" }, { "method": "POST", "path": "/rpc", "description": "The XRP Ledger's own READ commands against MAINNET — the twin of POST /testnet/rpc, so a developer who learned the sandbox changes the prefix and nothing else. Reads only (submitting is POST /submit); the node's in-band error (actNotFound, entryNotFound) rides in result with a 200, as on the node", "body": "{ method (one of the read commands), params (the command's own fields as an object) }", "response": "{ success, took, method, result (the node's own result, verbatim) }", "notes": "Same list as /testnet/rpc: account_channels, account_currencies, account_info, account_lines, account_nfts, account_objects, account_offers, account_tx, amm_info, book_changes, book_offers, channel_verify, deposit_authorized, feature, fee, gateway_balances, get_aggregate_price, ledger, ledger_closed, ledger_current, ledger_data, ledger_entry, ledger_header, ledger_index, manifest, mpt_holders, nft…" }, { "method": "GET", "path": "/submit/types", "description": "Every transaction type POST /submit relays, each with an example: examples[type] = { json (the reference example, unsigned), txid (a real Mainnet transaction of that type, when the reference names one), summary }", "response": "{ success, types[], examples: { [type]: { json, txid, summary } }, pool_size }" }, { "method": "GET", "path": "/submit/fee", "description": "Current network fees", "response": "{ success, base_fee, median_fee, minimum_fee, open_ledger_fee, current_ledger, current_queue_size, max_queue_size }" } ], "nft": [ { "method": "GET", "path": "/nft", "params": { "cid": "collection id", "issuer": "address", "taxon": "int (NFTokenTaxon; requires issuer)", "offset": "int (>=0)", "limit": "int (max 200, default 20; response echoes effective limit)", "sort": "created|time|rarity_rank|volume|cost.amount", "order": "asc|desc" }, "description": "List NFTs" }, { "method": "GET", "path": "/nft/{nftId}", "params": { "includeCollection": "bool" }, "description": "NFT by NFTokenID (64-char hex)" }, { "method": "GET", "path": "/nft/{nftId}/offers", "description": "Buy/sell offers for NFT" }, { "method": "GET", "path": "/nft/history", "params": { "NFTokenID": "64-char hex", "account": "r-address", "limit": "int (max 200; up to 50 ownership events past the limit, such as sales and transfers, are included too)", "types": "comma-separated: SALE|MINT|BURN|TRANSFER|CREATE_BUY_OFFER|CANCEL_BUY_OFFER|CREATE_SELL_OFFER|CANCEL_SELL_OFFER|ACCEPT_OFFER" }, "description": "NFT transaction history" }, { "method": "GET", "path": "/nft/history/{nftId}", "params": { "limit": "int (max 100)", "marker": "string" }, "description": "Live NFT history" } ], "txExplain": [ { "method": "GET", "path": "/tx-explain/{hash}", "description": "Human-readable transaction explanation (20 credits)", "response": "{ hash, extracted, summary: { summary, keyPoints[] }, timestamp }" } ], "accountTxExplain": [ { "method": "GET", "path": "/account-tx-explain/{account}", "description": "Wallet activity analysis and profiling (20 credits)", "params": { "limit": "int (200-400, default 200)" }, "response": "{ account, accountInfo, period, txCount, stats, analysis: { profile, headline, keyFindings[], riskLevel }, topAddresses[], model, disclaimer, timestamp }" } ], "tokenReview": [ { "method": "GET", "path": "/token/review/{id}", "description": "Token risk assessment (score 1-10, lower = safer)", "response": "{ md5, token, score, riskLevel, riskCount, positiveCount, supplyControl, creatorTokens[], timestamp }" }, { "method": "GET", "path": "/token/{md5}/related", "description": "Related projects: other tokens and NFT collections that share the audience of this token. An edge means wallets hold both and accounts post about both — it is NOT a wallet link and does not assert a shared operator (see /token/review for that).", "response": "{ success, took, count (rows in this response), truncated, subject, related[] } — each row: { type: token|collection, md5|collectionId, slug, name, sharedHolders, posters, wallets[] (a sample of the wallets holding both), posts[] (posts naming both), sameProject }" } ], "traders": [ { "method": "GET", "path": "/traders/{account}", "description": "Full trader profile", "params": { "limit": "int (max 200, default 50)", "offset": "int", "sortTokensBy": "volume|profit|trades|roi|lastTradeDate", "tokenIds": "comma-separated token md5s (filter, skips pagination)" }, "response": "{ success, address, rank, totalTokensTraded, holdingValue, tokenPerformance[], recentTokens[], pagination: { totalTokens (servable, capped 500), lifetimeTokens, truncated, limit, offset, hasMore } }" }, { "method": "GET", "path": "/traders/token-traders/{id}", "description": "Top traders for a token", "params": { "interval": "24h|7d|30d|all", "sortBy": "volume|pnl|trades|bought|sold|roi|wash|lastActive|unrealized|balance", "limit": "int (max 500, default 50)", "offset": "int", "minVolume": "float (filters all-time buyVolume)", "search": "address prefix" }, "response": "{ success, tokenId, interval, traders[], count (rows in this response), total (matching traders), offset, sortBy, limit }" }, { "method": "GET", "path": "/traders/rotations", "description": "Cross-token trader rotation analytics", "params": { "period": "24h|7d|30d (default 24h)", "minXrp": "float (default 1)", "limit": "int (max 100, default 50)" } }, { "method": "GET", "path": "/traders/rotations/{tokenId}", "description": "Trader rotations for a specific token", "params": { "period": "24h|7d|30d (default 24h)", "minXrp": "float (default 1)" }, "notes": "tokenId must be a raw md5 (no slug resolution)" }, { "method": "GET", "path": "/traders/{account}/rotations", "description": "Per-account token rotation flow (XRP bought/sold per token in window)", "params": { "period": "24h|7d|30d (default 24h)", "minXrp": "float (default 0.01)" }, "response": "{ success, period, account, totalTrades, tokensTraded, rotationCount, tokens[] }" } ], "analytics": [ { "method": "GET", "path": "/token/analytics/token/{id}", "description": "Token analytics" }, { "method": "GET", "path": "/token/analytics/token/{id}/traders", "params": { "offset": "int", "limit": "int (max 100, default 50)", "sort": "volume24h|volume7d|volume30d|volumeTotal|trades24h|tradesTotal|realizedPnl|unrealizedPnl|totalPnl|holding|lastTradeAt|firstTradeAt", "address": "filter" }, "description": "Top traders for token" }, { "method": "GET", "path": "/token/analytics/trader/{address}", "description": "Trader cumulative stats" }, { "method": "GET", "path": "/token/analytics/trader/{address}/tokens", "params": { "token": "token id" }, "description": "Trader token-specific metrics" }, { "method": "GET", "path": "/token/analytics/traders", "description": "All traders with cumulative stats", "params": { "offset": "int", "limit": "int (max 500, default 50)", "sort": "volume24h|volume7d|totalVolume|totalProfit|totalTrades|avgROI|winRate|lastTradeDate|washTradingScore|activityScore (unknown values fall back to volume24h)", "order": "asc|desc", "period": "24h|7d|30d|all", "startDate": "ISO", "endDate": "ISO", "minVolume": "float (filters volume24h)", "minTrades": "int", "minProfit": "float", "minROI": "float", "minTokens": "int", "address": "partial match", "includeAMM": "bool (default true)", "sourceTag": "int", "compact": "bool" } } ], "tokenFlow": [ { "method": "GET", "path": "/token/flow/{id}", "description": "Creator allocation and distribution analysis (precomputed)", "response": "{ success, token, summary, linkedAddresses[], exchangeBreakdown[], graph: { nodes[], edges[] }, processedAt, lastLedger } or { success, pending: true }", "notes": "{id} must be a raw md5 (no slug resolution); serves a precomputed document, no query params. summary.creatorAllocated/Delivered/Locked* describe the creator's own cut (escrow / check / issuer payment) and where it went; their percentages are measured against circulating supply PLUS anything still locked in escrow, since escrowed tokens sit outside every trustline. summary.placed* account for every…" } ], "news": [ { "method": "GET", "path": "/news", "auth": "Developer tier+ API key", "params": { "offset": "int (clamped >= 0)", "limit": "int (1-100, default 20)", "source": "filter (approved sources only)", "date": "YYYY-MM-DD (single-day filter)" }, "description": "Latest XRP news with sentiment", "response": "{ sentiment: { 24h, 7d, 30d, all }, sources[], data[], pagination: { offset, limit, total, totalPages } }" }, { "method": "GET", "path": "/news/search", "auth": "Developer tier+ API key", "params": { "q": "string (required)", "offset": "int (clamped >= 0)", "limit": "int (1-100, default 20)" }, "description": "Search news articles", "response": "{ query, sentiment, data[], pagination }" }, { "method": "GET", "path": "/news/unapproved-sources", "auth": "Developer tier+ API key", "params": { "offset": "int", "limit": "int (1-100, default 20)" }, "description": "News sources pending approval" }, { "method": "GET", "path": "/news/sentiment-chart", "auth": "Developer tier+ API key", "params": { "days": "int (1-365, default 30)" }, "description": "Historical sentiment analysis chart", "response": "{ labels[], bullish[], bearish[], neutral[], updated }" } ], "mentions": [ { "method": "GET", "path": "/mentions/search", "auth": "Developer tier+ API key", "params": { "q": "string (full-text search on tweet content, max 200 chars)", "author": "string (username prefix match, case-insensitive)", "token": "string (token name, ticker, or md5)", "from": "ISO date or unix ms (lower bound on tweetCreatedAt)", "to": "ISO date or unix ms (upper bound)", "minLikes": "int", "minViews": "int", "excludeSpam": "bool (default true; pass false to include spam-flagged tweets)", "excludeImpostors": "bool (filter out impostor accounts)", "sort": "recent|engagement|views|relevance (relevance requires q)", "limit": "int (max 100, default 20)", "offset": "int (default 0)" }, "description": "Agent-friendly search across X/Twitter mentions with full-text + filters. Returns enriched tweets with token name, spam/impostor flags." }, { "method": "GET", "path": "/mentions/feed", "auth": "Developer tier+ API key", "params": { "limit": "int (max 100, default 20)", "offset": "int (clamped >= 0)", "period": "1d|7d|30d|90d|all", "author": "string", "q": "string (full-text)", "excludeSpam": "bool (default true — spam rows removed in-query; pagination and count share the filtered row space; pass false to include)", "excludeImpostors": "bool (impostor rows removed in-query; also filters topAuthors)", "minViews": "int", "minLikes": "int", "sort": "recent|engagement|views|likes (default recent)" }, "description": "Global social feed with trending tokens, top authors, activity chart, and impostor list" }, { "method": "GET", "path": "/mentions/{md5}", "auth": "Developer tier+ API key", "params": { "period": "1d|7d|30d|90d|all", "author": "string", "limit": "int (max 100, default 20)", "offset": "int (clamped >= 0)" }, "description": "Per-token mention feed with stats, top mentioners, and activity chart" }, { "method": "GET", "path": "/mentions/spaces", "auth": "Developer tier+ API key", "params": { "limit": "int (hosts, max 500, default 200)", "offset": "int", "spacesLimit": "int (spaces per host, max 100, default 10)" }, "description": "X Space hosts with full history and inferred schedule (days/hour UTC). Returns all known space hosts sorted by most recent activity." }, { "method": "GET", "path": "/mentions/openapi.json", "auth": "Developer tier+ API key", "description": "OpenAPI 3.0 spec for the mentions endpoints (agent/MCP discoverable)" } ], "launch": [ { "method": "POST", "path": "/launch-token", "body": "{ currencyCode, tokenSupply, ammXrpAmount, name, origin, user, antiSnipe?, shield? (default true), imageData?, domain?, description?, telegram?, twitter?, userCheckAmount?, platformRetentionPercent?, ammTradingFee?, bundleRecipients?[] }", "description": "Create new token with AMM" }, { "method": "GET", "path": "/launch-token/status/{sessionId}", "description": "Launch session status" }, { "method": "GET", "path": "/launch-token/queue-status/{sessionId}", "description": "Queue position status" }, { "method": "POST", "path": "/launch-token/authorize", "body": "{ sessionId, userAddress }", "description": "Authorize trustline (anti-snipe)" }, { "method": "GET", "path": "/launch-token/auth-info/{issuer}/{currency}", "description": "Token authorization info" } ], "presale": [ { "method": "GET", "path": "/presale", "params": { "status": "'all' to include non-open" }, "description": "List presales (open by default)" }, { "method": "POST", "path": "/presale", "body": "{ currencyCode, name, origin, tokenSupply, goalXrp, softCapXrp, durationHours, tradingFee, creatorPct?, creatorVestDays?, buyerUnlockPct?, buyerVestDays?, imageData?, description?, twitter?, telegram?, website? }", "description": "Create a presale (issuer + sale wallets are provisioned server-side)" }, { "method": "POST", "path": "/presale/{id}/join", "body": "{ address, amountXrp }", "description": "Join — checks the wallet can fund the escrow above its reserve, returns the conditional EscrowCreate to sign; an unconfirmed slot may join again, an escrow that already landed is confirmed instead" }, { "method": "POST", "path": "/presale/{id}/confirm", "body": "{ address, txHash }", "description": "Confirm a signed escrow contribution" }, { "method": "POST", "path": "/presale/{id}/finalize", "description": "Finalize after deadline/goal: capture escrows, deliver claim Checks, seed AMM, blackhole wallets" } ], "xaman": [ { "method": "POST", "path": "/xaman/payload", "auth": "xrpl.to platform key (our own surfaces only; 403 otherwise)", "body": "{ txjson: { TransactionType, ... }, options?: { submit?, expire? (min, 1-60), return_url?: { web?, app? }, multisign?, pathfinding? }, custom_meta?: { identifier?, instruction? } }", "description": "Create a Xaman sign request — returns { uuid, next.always (open in Xaman), refs.qr_png, refs.websocket_status }. xrpl.to surfaces only (platform key); user_token is refused" }, { "method": "GET", "path": "/xaman/payload/{uuid}", "description": "Sign request status (live, never cached): meta.signed/expired/cancelled, response.account (SignIn answer), response.txid (submitted transaction)" }, { "method": "DELETE", "path": "/xaman/payload/{uuid}", "auth": "xrpl.to platform key (our own surfaces only; 403 otherwise)", "description": "Cancel an unsigned sign request (xrpl.to surfaces only)" } ], "referral": [ { "method": "GET", "path": "/referral/{address}", "description": "Get soldier profile" }, { "method": "GET", "path": "/referral/{address}/stats", "description": "Badge progress and tier stats" }, { "method": "GET", "path": "/referral/leaderboard/{type}", "params": { "type": "recruits|streak|season|whales", "limit": "int (default 100, max 500)", "offset": "int (default 0)" }, "description": "Leaderboard" }, { "method": "GET", "path": "/referral/meta/tiers", "description": "Tier definitions" }, { "method": "GET", "path": "/referral/meta/badges", "description": "Badge definitions" } ], "promotion": [ { "method": "GET", "path": "/promotion/pool/{md5}", "description": "Get promotion pool info (status, amounts, expiry)" }, { "method": "GET", "path": "/promotion/reward/{md5}/{account}", "description": "Get reward status for a token" }, { "method": "GET", "path": "/promotion/leaderboard/{md5}", "params": { "offset": "int (default 0)", "limit": "int (default 20, max 1000)" }, "description": "Per-token promoter leaderboard" }, { "method": "GET", "path": "/promotion/profile/{account}", "description": "Global promotion stats" }, { "method": "GET", "path": "/promotion/tiers", "description": "Promoter tier metadata" } ], "bridge": [ { "method": "GET", "path": "/bridge/currencies", "description": "List available exchange currencies" }, { "method": "GET", "path": "/bridge/estimate", "params": { "fromCurrency": "string", "toCurrency": "string", "fromAmount": "string", "fromNetwork": "string", "toNetwork": "string" }, "description": "Get exchange rate estimate" }, { "method": "GET", "path": "/bridge/min-amount", "params": { "fromCurrency": "string", "toCurrency": "string" }, "description": "Get minimum exchange amount" }, { "method": "POST", "path": "/bridge/create", "body": "{ fromCurrency, toCurrency, fromAmount, address, refundAddress? }", "description": "Create exchange" }, { "method": "GET", "path": "/bridge/status", "params": { "id": "string" }, "description": "Get exchange status" } ], "verify": [ { "method": "GET", "path": "/verify/pricing", "description": "Verification tier pricing" }, { "method": "GET", "path": "/verify/stripe/status/{sessionId}", "params": { "id": "string (required — token md5 or collection id)" }, "description": "Check Stripe verification payment status; fulfills if webhook was missed" }, { "method": "POST", "path": "/verify/request", "body": "{ type, id, tier, account }", "description": "Create XRP invoice for token/collection verification" }, { "method": "POST", "path": "/verify/confirm", "body": "{ invoiceId | txHash }", "description": "Confirm verification payment" }, { "method": "POST", "path": "/verify/stripe/checkout", "body": "{ type, id, tier, account }", "description": "Stripe checkout for verification" } ], "tweetVerify": [ { "method": "GET", "path": "/tweet/token/{md5}", "params": { "limit": "int (max 1000, default 20)", "offset": "int (clamped >= 0)" }, "description": "Tweet verifications for a token (md5) or NFT collection (slug)" }, { "method": "GET", "path": "/tweet/account/{account}", "params": { "limit": "int (max 1000, default 20)", "offset": "int (clamped >= 0)" }, "description": "Tweet verifications by account" }, { "method": "POST", "path": "/tweet/verify", "auth": "wallet signature", "body": "{ md5 (token md5 or NFT slug), tweetUrl, account, type?: token|nft }", "description": "Verify a promotional tweet and credit the wallet. One verification per wallet every 2 hours, up to 6 tokens per X account per UTC day, and a tweet earns from one pool." } ], "boost": [ { "method": "GET", "path": "/boost/quote/{md5}", "params": { "rank": "int" }, "description": "Get quote for boosting a token" }, { "method": "POST", "path": "/boost/purchase", "body": "{ md5, boostAmount, payerAddress }", "description": "Create boost payment request" }, { "method": "GET", "path": "/boost/verify/{invoiceId}", "description": "Verify payment and apply boost" }, { "method": "POST", "path": "/boost/stripe", "body": "{ md5, packId, payerAddress }", "description": "Create Stripe checkout for boost" }, { "method": "GET", "path": "/boost/stripe/{sessionId}", "params": { "wallet": "r-address (required, must match invoice payer)" }, "description": "Check Stripe boost payment status" } ], "scams": [ { "method": "GET", "path": "/scams/addresses", "params": { "category": "wallet_drainer|dust_spam|phishing|impersonation|fake_airdrop|other (optional)" }, "description": "THE canonical scam blocklist: top-level addresses[] is the deduped union of every blocked account (drainers, dust/token spam, phishing, impersonation, fake airdrops, NFT-scam issuers). Check a Destination/counterparty against it BEFORE a user signs. Real-time, never cached (Cache-Control: no-store) — poll every ~5s. Per-category sections (nftPhishing, paymentDrain) are additive metadata and may ov…" }, { "method": "GET", "path": "/scams", "description": "Full scam report with abuse statistics" }, { "method": "GET", "path": "/scams/tokens", "params": { "issuer": "address (REQUIRED)", "page": "int (default 1)", "limit": "int (default 50, max 100)" }, "description": "Tokens issued by one named issuer. issuer is required — this endpoint lists an issuer's tokens, it does not classify them. For a scam verdict use /scams/addresses or /scams/check/{account}." }, { "method": "GET", "path": "/scams/domains", "description": "Known scam domains with registrar info" }, { "method": "GET", "path": "/scams/nft", "description": "NFT scam accounts and recent sales" } ], "creatorActivity": [ { "method": "GET", "path": "/creator-activity/{id}", "description": "Token creator trading activity", "params": { "id": "md5 or creator r-address", "since": "unix ms — return events strictly newer (exclusive)", "before": "unix ms — return events strictly older (exclusive cursor)", "limit": "int (max 200)", "side": "buy|sell", "type": "event type", "stream": "bool" } }, { "method": "GET", "path": "/creator-activity/{id}/receiver/{address}", "description": "Creator activity filtered by recipient address" }, { "method": "GET", "path": "/whale-activity/feed", "description": "Global whale tape — the newest notable trades across ALL tokens. `tokens` maps each event md5 to its display identity (name, user, slug, verified)", "params": { "limit": "int (default 30, max 100)", "since": "unix ms — return events strictly newer (exclusive)", "minXrp": "float — minimum XRP size", "side": "buy|sell" }, "response": "{ success, took, count, events[], tokens{} }" }, { "method": "GET", "path": "/whale-activity/{id}", "description": "Whale social-proof trade events — top holders of major tokens, smart money, named accounts, whale-sized and fresh-wallet trades on this token", "params": { "id": "md5 or trader r-address", "since": "unix ms — return events strictly newer (exclusive)", "limit": "int (max 200)" } } ] }
Long arrays and strings are shortened in the example; Send request for the full answer.
What it does
This documentation (JSON). Browsers (Accept: text/html) are redirected to the human-readable docs.