curl --request GET \
--url https://public-api-v2.bags.fm/api/v1/evm/rh/tokens \
--header 'x-api-key: <api-key>'import requests
url = "https://public-api-v2.bags.fm/api/v1/evm/rh/tokens"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://public-api-v2.bags.fm/api/v1/evm/rh/tokens', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://public-api-v2.bags.fm/api/v1/evm/rh/tokens",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://public-api-v2.bags.fm/api/v1/evm/rh/tokens"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://public-api-v2.bags.fm/api/v1/evm/rh/tokens")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api-v2.bags.fm/api/v1/evm/rh/tokens")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"response": {
"items": [
{
"address": "<string>",
"name": "<string>",
"symbol": "<string>",
"metadataURI": "<string>",
"metadata": {
"image": "<string>",
"description": "<string>"
},
"curve": "<string>",
"feeShare": "<string>",
"poolId": "<string>",
"creator": "<string>",
"partner": "<string>",
"partnerFeeBps": 123,
"createdAtBlock": 123,
"createdAtTimestamp": 123,
"txHash": "<string>",
"migrated": true,
"migratedAtBlock": 123,
"migratedAtTimestamp": 123,
"quote": {
"address": "<string>",
"symbol": "<string>",
"decimals": 123,
"isNative": true
},
"priceEthPerToken": "<string>",
"bondingProgressPct": 123,
"priceQuotePerToken": "<string>",
"volume24hQuoteWei": "<string>",
"fees": {
"buyFeeBps": 123,
"sellFeeBps": 123,
"protocolBuyFeeBps": 123,
"protocolSellFeeBps": 123
}
}
],
"total": 123,
"totalTruncated": true
}
}{
"success": false,
"response": "<string>"
}{
"success": false,
"error": "<string>"
}{
"success": false,
"response": "<string>"
}Get Robinhood Token List
Get a paged list of Bags tokens (V1, V2, or V3) on Robinhood Chain with live enrichment (spot price and bonding progress). Each item carries priceEthPerToken/priceQuotePerToken (nullable) and bondingProgressPct, plus resolved metadata (image, description) and the launch’s quote asset (WETH unless the launch is a V3 launch quoted in an ERC20).
total is bounded by an internal count-scan cap (10k): when totalTruncated is true the real total is higher, so treat total as a lower bound and keep paging until items comes back short instead of using it to conclude pagination is exhausted.
curl --request GET \
--url https://public-api-v2.bags.fm/api/v1/evm/rh/tokens \
--header 'x-api-key: <api-key>'import requests
url = "https://public-api-v2.bags.fm/api/v1/evm/rh/tokens"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://public-api-v2.bags.fm/api/v1/evm/rh/tokens', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://public-api-v2.bags.fm/api/v1/evm/rh/tokens",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://public-api-v2.bags.fm/api/v1/evm/rh/tokens"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://public-api-v2.bags.fm/api/v1/evm/rh/tokens")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api-v2.bags.fm/api/v1/evm/rh/tokens")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"response": {
"items": [
{
"address": "<string>",
"name": "<string>",
"symbol": "<string>",
"metadataURI": "<string>",
"metadata": {
"image": "<string>",
"description": "<string>"
},
"curve": "<string>",
"feeShare": "<string>",
"poolId": "<string>",
"creator": "<string>",
"partner": "<string>",
"partnerFeeBps": 123,
"createdAtBlock": 123,
"createdAtTimestamp": 123,
"txHash": "<string>",
"migrated": true,
"migratedAtBlock": 123,
"migratedAtTimestamp": 123,
"quote": {
"address": "<string>",
"symbol": "<string>",
"decimals": 123,
"isNative": true
},
"priceEthPerToken": "<string>",
"bondingProgressPct": 123,
"priceQuotePerToken": "<string>",
"volume24hQuoteWei": "<string>",
"fees": {
"buyFeeBps": 123,
"sellFeeBps": 123,
"protocolBuyFeeBps": 123,
"protocolSellFeeBps": 123
}
}
],
"total": 123,
"totalTruncated": true
}
}{
"success": false,
"response": "<string>"
}{
"success": false,
"error": "<string>"
}{
"success": false,
"response": "<string>"
}total is bounded by an internal count-scan cap (10k). When totalTruncated is true, the real total is higher — treat total as a lower bound and keep paging until items comes back short, rather than using total to decide pagination is exhausted.Authorizations
API key authentication. Provide your API key as the header value.
Query Parameters
Number of tokens to return per page.
1 <= x <= 100Number of tokens to skip.
0 <= x <= 10000Filter by migration status: true for graduated tokens, false for tokens still bonding.
Filter by creator address. Accepts any casing; normalized to EIP-55 checksum form.
Field to order the list by.
createdAtTimestamp, migratedAtTimestamp Sort direction.
asc, desc Filter to launches settling in this quote asset (accepts any casing, normalized to EIP-55). Pass the WETH address to keep WETH-quoted launches, including V1/V2.
true keeps only launches with a non-WETH ERC20 quote asset; false keeps only WETH-quoted launches. V1/V2 launches are always WETH-quoted, so they never match quoted=true.
