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

# Migrating from Mobula

> Map Mobula's spot endpoints, streams and token fields to their equivalents here.

This guide maps Mobula's spot data API to this one: requests, authentication, chain IDs, streams, and every field on the token object.

## Key differences

| | Mobula | Chronos |
| - | - | - |
| Authentication | `Authorization: <key>`, `Authorization: Bearer <key>` or `x-api-key` | `Authorization: Bearer <key>` only |
| Keyless access | A rate-limited demo host | None; every `/v1` request needs a key |
| Chain IDs | `solana:solana`, `evm:8453`, `evm:56` | `solana`, `base`, `bsc`, `robinhood` |
| Token address | A query parameter | A path segment: `/v1/tokens/{chain}/{address}` |
| Prices and amounts | USD numbers | `{native, usd}` objects holding decimal strings |
| Windowed stats | Fused into the field name: `volume24hUSD` | Nested by window: `stats["24h"].volume` |
| Percentages | Named per field, such as `top10HoldingsPercentage` | Always 0–100, with a `Pct` suffix |

## Endpoints

| Mobula | Chronos |
| - | - |
| `GET /api/2/token/details` | `GET /v1/tokens/{chain}/{address}` |
| `GET /api/2/token/ohlcv-history` | `GET /v1/tokens/{chain}/{address}/ohlcv` |
| `GET /api/2/token/trades` | `GET /v1/tokens/{chain}/{address}/trades` |
| `POST /api/2/pulse` | `POST /v1/discovery` |

```bash theme={null}
# Mobula
curl "https://api.mobula.io/api/2/token/details?chainId=solana:solana&address=DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" \
  -H "Authorization: $MOBULA_KEY"

# Chronos
curl "https://{{API_HOST}}/v1/tokens/solana/DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" \
  -H "Authorization: Bearer $API_KEY"
```

## Streams

| Mobula stream | Channel here | Notes |
| - | - | - |
| `fast-trade` | [`spot.trades`](/reference/streams/spot-trades) | Subscribe by token, by wallet, or by identity feed |
| `ohlcv` | [`spot.candles`](/reference/streams/spot-candles) | One subscription per token, timeframe, metric and denomination |
| `token-details` | [`spot.tokens`](/reference/streams/spot-tokens) | Up to 100 tokens per subscription |

Mobula sends the API key inside each subscribe payload. Here, the key goes on the WebSocket handshake once, and every subscribe frame uses the same shape: `{"action": "subscribe", "channel": …, "filters": …}`. See [Connecting to streams](/streams/overview).

## Token object

Mobula field names below are from its `GET /api/2/token/details` response.

### Identity and market

| Mobula | Chronos |
| - | - |
| `address`, `name`, `symbol`, `decimals` | Same names |
| `blockchain`, `chainId` | `chain` |
| `logo` | Not on the token object |
| `priceUSD` | `price.usd`, with `price.native` alongside |
| `marketCapDilutedUSD` | `marketCap.usd`, which uses total supply |
| `liquidityUSD` | `liquidity.usd` |
| `totalSupply` | `supply` |
| `athUSD`, `athDate` | `ath.price.usd`, `ath.priceAt`, with `ath.marketCap` and `ath.marketCapAt` alongside |
| `deployer` | `creator`; `devFunding` also names who funded the creator |
| `createdAt`, an ISO date string | `createdAt`, in milliseconds |
| `exchange`, an object with `name` and `logo` | `dexes`, a list of venue names, deepest pool first |

### Windowed stats

Mobula fuses the window into each field name. Here, windows are keys under `stats`.

| Mobula | Chronos |
| - | - |
| `volume{W}USD` | `stats.{w}.volume.usd` |
| `priceChange{W}Percentage` | `stats.{w}.priceChangePct`, signed: `"-2.5"` is a 2.5% fall |
| `buys{W}`, `sells{W}` | `stats.{w}.buyCount`, `stats.{w}.sellCount` |
| `trades{W}` | `stats.{w}.buyCount` plus `stats.{w}.sellCount` |
| `volumeBuy{W}USD`, `volumeSell{W}USD` | `stats.{w}.buyVolume.usd`, `stats.{w}.sellVolume.usd` |

The windows differ:

| Mobula | Chronos |
| - | - |
| `5min`, `1h`, `6h`, `24h` | `5m`, `1h`, `6h`, `24h` |
| `1min`, `15min`, `4h`, `12h` | No equivalent |
| No equivalent | `30m` |

### Holders

| Mobula | Chronos |
| - | - |
| `holdersCount` | `holders.count` |
| `top10HoldingsPercentage` | `holders.top10Pct` |
| `devHoldingsPercentage` | `holders.devPct` |
| `insidersHoldingsPercentage`, `insidersCount` | `holders.insiderPct`, `holders.insiderCount` |
| `bundlersHoldingsPercentage`, `bundlersCount` | `holders.bundlerPct`, `holders.bundlerCount` |
| `snipersHoldingsPercentage`, `snipersCount` | `holders.sniperPct`, `holders.sniperCount` |
| `freshTradersHoldingsPercentage`, `freshTradersCount` | `holders.freshWalletPct`, `holders.freshWalletCount` |
| `proTradersHoldingsPercentage`, `proTradersCount` | `holders.proTraderPct`, `holders.proTraderCount` |
| No equivalent | `holders.fomoPct`, `holders.phishingPct` and `holders.fundedByCexPct` |

The two APIs classify wallets with their own rules, so the same field can read differently. See the [glossary](/resources/glossary#wallet-classifications) for the rules here.

### Security

| Mobula | Chronos |
| - | - |
| `security.isMintable` | `security.mintDisabled`, inverted |
| `security.transferPausable` | `security.transferBlockable`, which also covers freeze authorities and blacklists |
| `liquidityBurnPercentage` | `security.lpBurntPct` |
| `security.transferTax` | `security.transferFeeBps`, in basis points |

### Launchpad and metadata

| Mobula | Chronos |
| - | - |
| `source` | `launchpad` |
| `bondingPercentage` | `bondingCurvePct` |
| `bonded`, `bondedAt` | `graduatedAt`, `null` until graduation; `graduatedToPool` and `graduatedToDex` say where it went |
| `description` | `metadata.description` |
| `socials.twitter`, `socials.website`, `socials.telegram` | `metadata.twitter`, `metadata.website`, `metadata.telegram` |
| A Discord link in `socials.others` | `metadata.discord` |
| `dexscreenerSocialPaid`, `dexscreenerSocialPaidDate` | An entry in `platforms`: `{"platform": "dexScreener", "isPaid": true, "paidAt": …}` |
| `isMayhemMode` | An entry in `annotations`: `{"kind": "mayhem_mode"}` |
| `totalFeesPaidUSD` | No single total. `totals.fees` splits fees into `transaction`, `validator`, `platform` and `dex`, which must not be added together. |

## Checklist

* [ ] Move the key to `Authorization: Bearer`, on REST requests and the stream handshake.
* [ ] Replace chain IDs with slugs.
* [ ] Move token addresses from query parameters into the path.
* [ ] Parse amounts as decimal strings, and read `.usd` from money objects.
* [ ] Read windowed stats from `stats`.
* [ ] Switch error handling to `error.code`. See [Errors and retries](/concepts/errors).
* [ ] Move stream subscriptions to the `action` / `channel` / `filters` frame.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.