npm package: @geeklad/jupiter-token-api
Description: TypeScript client for Jupiter Token API v2 with caching and request deduplication
Latest version: 1.0.0

# @geeklad/jupiter-token-api

A TypeScript client for the
[Jupiter Token API v2](https://dev.jup.ag/api-reference/tokens/v2) — search,
browse, and retrieve token data on Solana with built-in caching and request
deduplication.

## Features

- **Token cache** — previously fetched tokens are stored in an in-memory cache
  so repeated lookups never hit the network twice
- **Deduplication of simultaneous calls** — concurrent requests for the same
  tokens share a single in-flight API call; a 10 ms debounce window batches
  requests arriving together into one network round-trip
- **Free lite endpoint** — works out of the box with no API key using the public
  `https://lite-api.jup.ag/tokens/v2` endpoint
- **Production endpoint** — pass an `apiKey` to use the higher-rate-limit
  `https://api.jup.ag/tokens/v2` endpoint
- **Dual ESM/CJS output** — ships both `import` and `require` entry points with
  full TypeScript types

## Installation

```bash
npm install @geeklad/jupiter-token-api
```

Requires Node.js 18 or later (native `fetch` is used internally).

## Quick Start

```ts
import { createJupiterTokenAPI } from "@geeklad/jupiter-token-api";

// No API key — uses the free lite endpoint
const api = createJupiterTokenAPI();

// Search by mint address, comma-separated for multiple
const tokens = await api.search(
  "So11111111111111111111111111111111111111112,EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
);
console.log(tokens);

// Get recently added tokens
const recent = await api.getRecent();
```

### With an API key (production endpoint)

```ts
import { createJupiterTokenAPI } from "@geeklad/jupiter-token-api";

const api = createJupiterTokenAPI({ apiKey: "your-api-key-here" });

const tokens = await api.search("So11111111111111111111111111111111111111112");
```

## API Reference

### `createJupiterTokenAPI(options?)` / `new JupiterTokenAPI(options?)`

Creates a client instance.

| Option         | Type     | Default | Description                                                                                       |
| -------------- | -------- | ------- | ------------------------------------------------------------------------------------------------- |
| `apiKey`       | `string` | —       | API key for the production endpoint. Omit to use the free lite endpoint.                          |
| `cacheMaxSize` | `number` | `1000`  | Maximum number of token entries to hold in the in-memory cache. Oldest entries are evicted first. |

---

### `search(query: string): Promise<MintInformation[]>`

Search for tokens by mint address or symbol. Pass a single mint address, a
single symbol, or a comma-separated list of mint addresses for bulk lookups.
Comma-separated queries only work with mint addresses — use separate calls for
symbol lookups.

```ts
// Single symbol
const sol = await api.search("SOL");

// Single mint address
const usdc = await api.search("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");

// Multiple mint addresses (comma-separated)
const results = await api.search(
  "So11111111111111111111111111111111111111112,EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
);
```

Cached results are returned immediately without a network call. Multiple
concurrent calls for the same tokens are automatically collapsed into a single
request.

---

### `getByTag(tag: TagQuery): Promise<MintInformation[]>`

Fetch tokens by tag.

```ts
const verified = await api.getByTag("verified");
const lstTokens = await api.getByTag("lst");
```

`TagQuery` = `'lst' | 'verified'`

---

### `getByCategory(category: CategoryType, interval: IntervalType, limit?: number): Promise<MintInformation[]>`

Fetch tokens ranked by a category over a time interval.

```ts
const trending = await api.getByCategory("toptrending", "1h", 20);
```

| Parameter  | Type           | Values                                                  |
| ---------- | -------------- | ------------------------------------------------------- |
| `category` | `CategoryType` | `'toporganicscore'` \| `'toptraded'` \| `'toptrending'` |
| `interval` | `IntervalType` | `'5m'` \| `'1h'` \| `'6h'` \| `'24h'`                   |
| `limit`    | `number`       | Optional result count cap                               |

---

### `getRecent(): Promise<MintInformation[]>`

Fetch recently added tokens.

```ts
const newTokens = await api.getRecent();
```

---

### `getContent(mints: string[]): Promise<MultipleMintsResponse>`

Fetch community content (summaries, news, tweets) for a set of mint addresses.

```ts
const content = await api.getContent([
  "So11111111111111111111111111111111111111112",
  "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
]);
```

---

### `getContentCooking(): Promise<CookingTokensResponse>`

Fetch content for tokens currently in the "cooking" (pre-launch) state.

```ts
const cooking = await api.getContentCooking();
```

---

### `getContentFeed(mint: string, page?: number, limit?: number): Promise<FeedResponse>`

Fetch the paginated content feed for a specific token.

```ts
const feed = await api.getContentFeed(
  "So11111111111111111111111111111111111111112",
  1, // page (default: 1)
  50, // limit (default: 50)
);
```

---

### Cache management

```ts
api.getSearchCacheSize(); // number of cached entries
api.clearSearchCache(); // empty the cache
```

## TypeScript

All types are exported from the package root:

```ts
import type {
  Audit,
  CategoryType,
  CookingTokensResponse,
  FeedResponse,
  IntervalType,
  JupiterTokenAPIOptions,
  MintInformation,
  MultipleMintsResponse,
  SwapStats,
  TagQuery,
} from "@geeklad/jupiter-token-api";
```

## API Reference

Full Jupiter Token API v2 documentation:
https://dev.jup.ag/api-reference/tokens/v2

## License

MIT