> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ralphstudio.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Tokens

> Query fungible token and NFT metadata, holders, and activity from the Alephium indexer.

The indexer tracks all tokens issued on Alephium, both fungible tokens (FTs) and non-fungible tokens (NFTs). These endpoints let you fetch metadata, holder lists, transfer history, and price information where available.

## Get token metadata

Returns metadata for a fungible token by its contract address.

```bash theme={null}
curl "https://rpc.ralphstudio.xyz/{slug}/indexer/tokens/{token-id}" \
  -H "Authorization: Bearer API_KEY"
```

```json theme={null}
{
  "id": "b2d71c116408ae47a83c6db0571a1b2d1f58dc87ac5d7e8e4c2a3d1f9e0b8c4",
  "symbol": "USDT",
  "name": "Tether USD",
  "decimals": 6,
  "totalSupply": "1000000000000"
}
```

Tokens that have not registered metadata on-chain will return only `id` and `totalSupply`. Always check for the presence of `symbol` and `name` before rendering.

## Get all fungible tokens

Returns a paginated list of all known fungible tokens on the network.

```bash theme={null}
curl "https://rpc.ralphstudio.xyz/{slug}/indexer/tokens/fungible-tokens?page=1&limit=20" \
  -H "Authorization: Bearer API_KEY"
```

```json theme={null}
{
  "tokens": [
    {
      "id": "b2d71c...",
      "symbol": "USDT",
      "name": "Tether USD",
      "decimals": 6,
      "totalSupply": "1000000000000"
    },
    {
      "id": "c3e82d...",
      "symbol": "WBTC",
      "name": "Wrapped Bitcoin",
      "decimals": 8,
      "totalSupply": "21000000000000000"
    }
  ],
  "total": 84
}
```

## Get all NFT collections

Returns a paginated list of known NFT collections.

```bash theme={null}
curl "https://rpc.ralphstudio.xyz/{slug}/indexer/tokens/nft-collections?page=1&limit=20" \
  -H "Authorization: Bearer API_KEY"
```

```json theme={null}
{
  "collections": [
    {
      "address": "27Gsc5...",
      "collectionUri": "https://metadata.example.com/collection.json",
      "totalSupply": "1000"
    }
  ],
  "total": 12
}
```

## Get NFT metadata

Returns metadata for a single NFT by its token contract address.

```bash theme={null}
curl "https://rpc.ralphstudio.xyz/{slug}/indexer/tokens/{token-id}/nft" \
  -H "Authorization: Bearer API_KEY"
```

```json theme={null}
{
  "id": "d4f93e...",
  "collectionAddress": "27Gsc5...",
  "nftIndex": "42",
  "tokenUri": "https://metadata.example.com/42.json",
  "image": "https://images.example.com/42.png",
  "name": "Alephium Punk #42",
  "description": "A unique punk on Alephium."
}
```

`nftIndex` is the position of this NFT within its collection contract. `tokenUri` points to the off-chain JSON metadata, the indexer does not cache the contents of that URI.

## Get token transactions

Returns paginated transfer history for a token across all addresses.

```bash theme={null}
curl "https://rpc.ralphstudio.xyz/{slug}/indexer/tokens/{token-id}/transactions?page=1&limit=20" \
  -H "Authorization: Bearer API_KEY"
```

```json theme={null}
[
  {
    "hash": "503a2c...",
    "blockHash": "00000000ab3c...",
    "timestamp": 1748476800000,
    "inputs": [...],
    "outputs": [...],
    "gasAmount": 20000,
    "gasPrice": "100000000000",
    "scriptExecutionOk": true
  }
]
```

## Get token holders

Returns the top holders of a fungible token sorted by balance descending.

```bash theme={null}
curl "https://rpc.ralphstudio.xyz/{slug}/indexer/tokens/{token-id}/addresses?page=1&limit=20" \
  -H "Authorization: Bearer API_KEY"
```

```json theme={null}
{
  "holders": [
    {
      "address": "1DrDyTr9...",
      "balance": "500000000000",
      "lockedBalance": "0"
    },
    {
      "address": "1AujpupF...",
      "balance": "250000000000",
      "lockedBalance": "0"
    }
  ],
  "total": 312
}
```

## Get NFTs in a collection

Returns all NFTs belonging to a specific collection contract.

```bash theme={null}
curl "https://rpc.ralphstudio.xyz/{slug}/indexer/tokens/nft-collections/{collection-address}/nfts?page=1&limit=20" \
  -H "Authorization: Bearer API_KEY"
```

```json theme={null}
{
  "nfts": [
    {
      "id": "d4f93e...",
      "nftIndex": "0",
      "tokenUri": "https://metadata.example.com/0.json"
    },
    {
      "id": "e5a04f...",
      "nftIndex": "1",
      "tokenUri": "https://metadata.example.com/1.json"
    }
  ],
  "total": 1000
}
```

## Distinguishing FTs from NFTs

The indexer does not tag a token as FT or NFT in every response. A reliable way to tell them apart:

```javascript theme={null}
function isNFT(token) {
  // NFTs always have a supply of exactly 1
  return token.totalSupply === "1";
}

function formatAmount(rawAmount, decimals) {
  // Fungible tokens use fixed-point amounts
  return Number(rawAmount) / Math.pow(10, decimals);
}
```

If `decimals` is missing from the metadata response, treat the token as an NFT candidate and fetch `/tokens/{id}/nft` to confirm.

## Building a token portfolio view

Combine the address tokens endpoint with the metadata endpoint to render a full portfolio:

```javascript theme={null}
const BASE = "https://rpc.ralphstudio.xyz/{slug}/indexer";
const API_KEY = "API_KEY";

async function getPortfolio(address) {
  // Step 1: get all token balances for the address
  const holdingsRes = await fetch(`${BASE}/addresses/${address}/tokens`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
  });
  const holdings = await holdingsRes.json();

  // Step 2: fetch metadata for each token in parallel
  const withMeta = await Promise.all(
    holdings.map(async (holding) => {
      const metaRes = await fetch(`${BASE}/tokens/${holding.tokenId}`, {
        headers: { Authorization: `Bearer ${API_KEY}` },
      });
      const meta = await metaRes.json();
      return {
        ...holding,
        symbol: meta.symbol ?? holding.tokenId.slice(0, 8),
        name: meta.name ?? "Unknown Token",
        decimals: meta.decimals ?? 0,
        formattedBalance: meta.decimals
          ? Number(holding.balance) / Math.pow(10, meta.decimals)
          : holding.balance,
      };
    }),
  );

  return withMeta;
}
```

For production use, cache the metadata responses, token metadata is immutable once set on-chain and does not change.

## Parameters reference

| Parameter          | Type    | Description                              |
| ------------------ | ------- | ---------------------------------------- |
| token-id           | string  | Token contract address                   |
| collection-address | string  | NFT collection contract address          |
| page               | integer | Page number (default: 1)                 |
| limit              | integer | Results per page (default: 20, max: 100) |
