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

# How to Find Bonding Curve Address of a Token on Solana, Base, BNB & More

> Learn how to retrieve the bonding curve address for tokens using Mobula's API. Covers pump.fun, clanker, moonshot, and other bonding curve protocols across multiple chains.

When working with tokens that use bonding curves (like pump.fun on Solana or clanker on Base), you often need to find the bonding curve contract address to interact with the pool before it migrates to a traditional AMM. This cookbook shows you two methods to retrieve bonding curve addresses using Mobula's API.

***

## Two Methods to Find Bonding Curves

### Method 1: Using token/details (Recommended)

The simplest way - directly get the `bondingCurveAddress` field:

```bash theme={null}
curl -X GET "https://api.mobula.io/api/2/token/details?address=TOKEN_ADDRESS" \
  -H "Authorization: YOUR_API_KEY"
```

### Method 2: Using token/markets

List ALL pools/markets for a token, then find the bonding curve by matching the pool `type` with the token's `source`:

```bash theme={null}
curl -X GET "https://api.mobula.io/api/2/token/markets?address=TOKEN_ADDRESS" \
  -H "Authorization: YOUR_API_KEY"
```

***

## Understanding Bonding Curves

A bonding curve is a pricing mechanism where token price increases as more tokens are purchased. Many protocols use bonding curves to bootstrap liquidity for new tokens before eventually migrating to traditional AMM pools once a threshold is reached.

### Key Concepts

**`source`**: The protocol that launched the token (e.g., "pumpfun", "clanker", "moonshot")

**`type`**: The pool type identifier (e.g., "pumpfun", "clanker", "uniswap-v2")

**Bonding Curve Pool**: When a token's `source` matches a pool's `type`, that pool is the bonding curve. For example:

* Token source: "pumpfun" → Pool type: "pumpfun" = Bonding curve
* Token source: "clanker" → Pool type: "clanker" = Bonding curve

### Key Response Fields

| Field                 | Type           | Description                                  |
| --------------------- | -------------- | -------------------------------------------- |
| `source`              | string         | Protocol that launched the token             |
| `type`                | string         | Pool type identifier                         |
| `bondingCurveAddress` | string \| null | Contract address of the bonding curve pool   |
| `bonded`              | boolean        | Whether token completed bonding and migrated |
| `bondingPercentage`   | number         | Progress towards bonding completion (0-100%) |

***

## Method 1: Using token/details (Simplest)

### TypeScript

```typescript theme={null}
import { MobulaClient } from '@mobula/sdk';

const client = new MobulaClient({
  apiKey: process.env.MOBULA_API_KEY
});

async function getBondingCurveFromDetails(
  tokenAddress: string,
  blockchain?: string
) {
  const response = await client.fetchTokenDetails({
    address: tokenAddress,
    blockchain: blockchain
  });
  
  const token = response.data;
  
  return {
    bondingCurveAddress: token.bondingCurveAddress,
    bonded: token.bonded,
    bondingPercentage: token.bondingPercentage,
    source: token.source,
    poolAddress: token.poolAddress
  };
}

// Example: pump.fun token on Solana
const result = await getBondingCurveFromDetails(
  'HLwEJQVCQMVdRhFg1YKKgNAnCwUk4eboMTtdBtpump',
  'solana'
);

console.log(result);
// {
//   bondingCurveAddress: "7xKp...abc123",
//   bonded: false,
//   bondingPercentage: 67.5,
//   source: "pumpfun",
//   poolAddress: "7xKp...abc123"
// }
```

### Python

```python theme={null}
import requests

API_KEY = 'YOUR_API_KEY'
BASE_URL = 'https://api.mobula.io/api/2'

def get_bonding_curve_from_details(token_address: str, blockchain: str = None) -> dict:
    params = {'address': token_address}
    if blockchain:
        params['blockchain'] = blockchain
    
    response = requests.get(
        f'{BASE_URL}/token/details',
        params=params,
        headers={'Authorization': API_KEY}
    )
    response.raise_for_status()
    token = response.json().get('data', {})
    
    return {
        'bonding_curve_address': token.get('bondingCurveAddress'),
        'bonded': token.get('bonded'),
        'bonding_percentage': token.get('bondingPercentage'),
        'source': token.get('source'),
        'pool_address': token.get('poolAddress')
    }

# Example
result = get_bonding_curve_from_details(
    'HLwEJQVCQMVdRhFg1YKKgNAnCwUk4eboMTtdBtpump',
    'solana'
)
print(result)
```

***

## Method 2: Using token/markets (Advanced)

This method lists ALL pools and finds the bonding curve by matching pool `type` with token `source`.

### TypeScript

```typescript theme={null}
async function getBondingCurveFromMarkets(
  tokenAddress: string,
  blockchain?: string
) {
  const response = await client.fetchTokenMarkets({
    address: tokenAddress,
    blockchain: blockchain,
    limit: 25
  });
  
  const markets = response.data;
  
  if (markets.length === 0) {
    return { error: 'No markets found' };
  }
  
  // Get token source from any market (all markets have same base token)
  const tokenSource = markets[0].base.source;
  
  // Find bonding curve: pool type matches token source
  const bondingCurve = markets.find(m => m.type === tokenSource);
  
  if (!bondingCurve) {
    return {
      status: 'no-bonding-curve',
      message: `No bonding curve found (source: ${tokenSource})`
    };
  }
  
  return {
    bondingCurveAddress: bondingCurve.address,
    bondingPercentage: bondingCurve.bondingPercentage,
    bonded: bondingCurve.bonded,
    source: tokenSource,
    poolType: bondingCurve.type,
    liquidityUSD: bondingCurve.liquidityUSD,
    exchange: bondingCurve.exchange.name
  };
}

// Example: pump.fun token
const result = await getBondingCurveFromMarkets(
  'HLwEJQVCQMVdRhFg1YKKgNAnCwUk4eboMTtdBtpump',
  'solana'
);

console.log(result);
// {
//   bondingCurveAddress: "7xKp...abc123",
//   bondingPercentage: 67.5,
//   bonded: false,
//   source: "pumpfun",
//   poolType: "pumpfun",
//   liquidityUSD: 45000.50,
//   exchange: "Pump.fun"
// }
```

### Python

```python theme={null}
def get_bonding_curve_from_markets(token_address: str, blockchain: str = None) -> dict:
    params = {'address': token_address, 'limit': 25}
    if blockchain:
        params['blockchain'] = blockchain
    
    response = requests.get(
        f'{BASE_URL}/token/markets',
        params=params,
        headers={'Authorization': API_KEY}
    )
    response.raise_for_status()
    markets = response.json().get('data', [])
    
    if not markets:
        return {'error': 'No markets found'}
    
    # Get token source from first market
    token_source = markets[0]['base'].get('source')
    
    # Find bonding curve: pool type matches token source
    bonding_curve = next((m for m in markets if m.get('type') == token_source), None)
    
    if not bonding_curve:
        return {
            'status': 'no-bonding-curve',
            'message': f'No bonding curve found (source: {token_source})'
        }
    
    return {
        'bonding_curve_address': bonding_curve['address'],
        'bonding_percentage': bonding_curve.get('bondingPercentage'),
        'bonded': bonding_curve.get('bonded'),
        'source': token_source,
        'pool_type': bonding_curve.get('type'),
        'liquidity_usd': bonding_curve.get('liquidityUSD'),
        'exchange': bonding_curve['exchange']['name']
    }

# Example
result = get_bonding_curve_from_markets(
    'HLwEJQVCQMVdRhFg1YKKgNAnCwUk4eboMTtdBtpump',
    'solana'
)
print(result)
```

***

## How It Works

### Understanding the Matching Logic

When you query `token/markets`, you get ALL pools for a token:

```json theme={null}
{
  "data": [
    {
      "address": "7xKp...abc123",
      "type": "pumpfun",              // Pool type
      "bonded": false,
      "bondingPercentage": 67.5,
      "base": {
        "source": "pumpfun",          // Token source
        "address": "HLwEJQ...",
        "symbol": "MYTOKEN"
      }
    },
    {
      "address": "8yBp...def456",
      "type": "raydium-v4",           // Different pool type
      "bonded": true,
      "base": {
        "source": "pumpfun",          // Same token source
        "address": "HLwEJQ...",
        "symbol": "MYTOKEN"
      }
    }
  ]
}
```

**The bonding curve pool is where `type` matches `source`**:

* Pool 1: `type: "pumpfun"` = `source: "pumpfun"` ✅ This is the bonding curve!
* Pool 2: `type: "raydium-v4"` ≠ `source: "pumpfun"` ❌ This is a migrated pool

### Response Structure (token/details)

```json theme={null}
{
  "data": {
    "address": "HLwEJQVCQMVdRhFg1YKKgNAnCwUk4eboMTtdBtpump",
    "symbol": "MYTOKEN",
    "source": "pumpfun",
    "bondingCurveAddress": "7xKp...abc123",
    "bonded": false,
    "bondingPercentage": 67.5,
    "poolAddress": "7xKp...abc123",
    "priceUSD": 0.000123
  }
}
```

### Response Structure (token/markets)

```json theme={null}
{
  "data": [
    {
      "address": "7xKp...abc123",
      "type": "pumpfun",
      "blockchain": "Solana",
      "bonded": false,
      "bondingPercentage": 67.5,
      "exchange": {
        "name": "Pump.fun"
      },
      "liquidityUSD": 45000.50,
      "volume24hUSD": 125000.00,
      "base": {
        "address": "HLwEJQVCQMVdRhFg1YKKgNAnCwUk4eboMTtdBtpump",
        "symbol": "MYTOKEN",
        "source": "pumpfun"
      }
    }
  ]
}
```

***

## Protocol-Specific Examples

### Pump.fun (Solana)

```typescript theme={null}
async function getPumpfunBondingCurve(mintAddress: string) {
  const response = await client.fetchTokenMarkets({
    address: mintAddress,
    blockchain: 'solana'
  });
  
  // Find pool where type matches source "pumpfun"
  const pumpfunMarket = response.data.find(m => m.type === 'pumpfun');
  
  return pumpfunMarket ? {
    bondingCurveAddress: pumpfunMarket.address,
    progress: pumpfunMarket.bondingPercentage,
    bonded: pumpfunMarket.bonded,
    liquiditySOL: pumpfunMarket.liquidityUSD / 150
  } : null;
}
```

### Clanker (Base)

```typescript theme={null}
async function getClankerBondingCurve(tokenAddress: string) {
  const response = await client.fetchTokenMarkets({
    address: tokenAddress,
    blockchain: 'base'
  });
  
  // Find pool where type matches source "clanker"
  const clankerMarket = response.data.find(m => m.type === 'clanker');
  
  return clankerMarket ? {
    bondingCurveAddress: clankerMarket.address,
    progress: clankerMarket.bondingPercentage,
    bonded: clankerMarket.bonded
  } : null;
}
```

### Moonshot (Solana)

```typescript theme={null}
async function getMoonshotBondingCurve(mintAddress: string) {
  const response = await client.fetchTokenMarkets({
    address: mintAddress,
    blockchain: 'solana'
  });
  
  // Find pool where type matches source "moonshot"
  const moonshotMarket = response.data.find(m => m.type === 'moonshot');
  
  return moonshotMarket ? {
    bondingCurveAddress: moonshotMarket.address,
    progress: moonshotMarket.bondingPercentage,
    bonded: moonshotMarket.bonded
  } : null;
}
```

### Generic Function for Any Protocol

```typescript theme={null}
async function getBondingCurveBySource(
  tokenAddress: string,
  blockchain?: string
) {
  const response = await client.fetchTokenMarkets({
    address: tokenAddress,
    blockchain: blockchain
  });
  
  const markets = response.data;
  if (markets.length === 0) return null;
  
  // Get token source
  const source = markets[0].base.source;
  
  // Find pool matching the source
  const bondingCurve = markets.find(m => m.type === source);
  
  return bondingCurve ? {
    bondingCurveAddress: bondingCurve.address,
    source: source,
    poolType: bondingCurve.type,
    bonded: bondingCurve.bonded,
    bondingPercentage: bondingCurve.bondingPercentage,
    exchange: bondingCurve.exchange.name
  } : null;
}
```

***

## Advanced: Monitor Bonding Progress

```typescript theme={null}
async function monitorBondingProgress(tokenAddress: string, blockchain: string) {
  setInterval(async () => {
    const response = await client.fetchTokenDetails({
      address: tokenAddress,
      blockchain: blockchain
    });
    
    const token = response.data;
    
    if (token.bonded) {
      console.log('Token has completed bonding!');
      console.log(`Migrated from ${token.source} to new pool`);
      return;
    }
    
    console.log(`Source: ${token.source}`);
    console.log(`Progress: ${token.bondingPercentage?.toFixed(2)}%`);
    console.log(`Bonding curve: ${token.bondingCurveAddress}`);
    
    if (token.bondingPercentage && token.bondingPercentage > 95) {
      console.log('Warning: Bonding almost complete!');
    }
  }, 10000);
}
```

***

## Source to Pool Type Mapping

Common bonding curve protocols and their identifiers:

| Protocol          | Source Value        | Pool Type Value     | Chains    |
| ----------------- | ------------------- | ------------------- | --------- |
| Pump.fun          | `pumpfun`           | `pumpfun`           | Solana    |
| Moonshot          | `moonshot`          | `moonshot`          | Solana    |
| Clanker           | `clanker`           | `clanker`           | Base      |
| Flap              | `flap`              | `flap`              | Base, BNB |
| Nadfun            | `nadfun`            | `nadfun`            | Base      |
| Mana              | `mana`              | `mana`              | Base      |
| Raydium Launchlab | `raydium-launchlab` | `raydium-launchlab` | Solana    |
| Boop              | `boop`              | `boop`              | Solana    |

***

## Best Practices

<Tip>
  **Use token/details for simplicity**: If you only need the bonding curve address, use `token/details` which directly returns `bondingCurveAddress`.
</Tip>

<Tip>
  **Match source with type**: When using `token/markets`, find the pool where `type` matches the token's `source` - that's your bonding curve.
</Tip>

<Warning>
  **Bonding curve addresses become inactive**: Once `bonded: true`, the bonding curve pool is no longer active. Token has migrated to a new pool.
</Warning>

<Info>
  **Multiple pools are normal**: `token/markets` returns ALL pools for a token (bonding curve + migrated pools). The bonding curve is just one of them.
</Info>

***

## Troubleshooting

### Issue: No pool matches token source

**Problem**: No pool where `type` equals token `source`

**Solutions**:

1. Token may have completed bonding (check `bonded: true`)
2. Token may not have originated from a bonding curve
3. Use `token/details` to check `bondingCurveAddress` directly
4. Verify token address is correct

**Example**:

```typescript theme={null}
// Token source: "pumpfun" but no pool with type: "pumpfun"
// This means token has completed bonding
const markets = response.data;
const source = markets[0].base.source; // "pumpfun"
const bondingCurve = markets.find(m => m.type === source); // null
// Check markets[0].bonded === true
```

### Issue: bondingCurveAddress is null

**Problem**: `token/details` returns `bondingCurveAddress: null`

**Solutions**:

1. Token has completed bonding - check `bonded: true`
2. Token didn't launch via bonding curve
3. Check `poolAddress` for current active pool

### Issue: Multiple pools with same type

**Problem**: Multiple pools found with matching `type`

**Solution**: This is unusual but possible. Choose based on:

* Pool with `bonded: false` (active bonding curve)
* Highest `liquidityUSD`
* Most recent `createdAt` date

***

## Comparison: token/details vs token/markets

| Feature           | token/details                        | token/markets                                       |
| ----------------- | ------------------------------------ | --------------------------------------------------- |
| **Simplicity**    | ✅ Direct `bondingCurveAddress` field | Requires finding pool where `type` matches `source` |
| **Data Returned** | Single token info                    | All pools/markets for token                         |
| **Use Case**      | Quick bonding curve lookup           | Need all pool details, volumes, liquidity           |
| **Performance**   | Faster (single token)                | Slower (lists all pools)                            |
| **Best For**      | Simple bonding curve address lookup  | Market analysis, comparing pools                    |

***

## Related Resources

<CardGroup cols={2}>
  <Card title="Token Details API" icon="info-circle" href="/rest-api-reference/endpoint/token-details">
    Get bondingCurveAddress directly
  </Card>

  <Card title="Token Markets API" icon="chart-line" href="/rest-api-reference/endpoint/token-markets">
    List all pools for a token
  </Card>

  <Card title="Market Details API" icon="database" href="/rest-api-reference/endpoint/market-details">
    Detailed info about specific pools
  </Card>

  <Card title="Swap Execution API" icon="exchange" href="/rest-api-reference/endpoint/swap-instructions">
    Execute swaps on bonding curves
  </Card>
</CardGroup>

***

## Get Started

**[Create a free Mobula API key](https://admin.mobula.io/auth/sign-in) and start finding bonding curve addresses today!**

***

## Need Help?

<CardGroup cols={4}>
  <Card title="Telegram" icon="telegram" href="https://t.me/mobuladevelopers">
    Fast support
  </Card>

  <Card title="Discord" icon="discord" href="https://discord.gg/JVT7xKm3AD">
    Community
  </Card>

  <Card title="Slack" icon="slack" href="https://join.slack.com/t/mobulaapi/shared_invite/zt-29zrrpjnl-I0tyD73sy7zKy8q~KLL3Ug">
    Enterprise
  </Card>

  <Card title="Email" icon="envelope" href="mailto:contact@mobulalabs.org">
    Contact us
  </Card>
</CardGroup>
