npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@codifydoo/gamma-client

v1.0.3

Published

TypeScript client library for Polymarket Gamma API (read-only market data)

Downloads

301

Readme

Gamma Client

A production-ready TypeScript client library for the Polymarket Gamma API (read-only market data).

npm version Build Status Coverage Status

Features

  • 🚀 Full API Coverage - All 28+ endpoints across 8 domains
  • 🔒 Type Safety - Strict TypeScript types with no any
  • Runtime Validation - Zod schemas for request/response validation
  • 🔄 Retry Logic - Exponential backoff with jitter for resilience
  • Rate Limiting - Token bucket implementation for polite API usage
  • 💾 Caching - Optional in-memory TTL cache for performance
  • 🔧 Normalization - Automatic parsing of JSON-encoded arrays
  • 📖 Comprehensive Docs - JSDoc comments and runnable examples

Installation

npm install @codifydoo/gamma-client

Quick Start

import { GammaClient } from '@codifydoo/gamma-client';

const client = new GammaClient({
  baseURL: 'https://gamma-api.polymarket.com',
  timeoutMs: 10_000,
  retries: 2,
  rateLimit: { burst: 5, ratePerSec: 5 },
  cache: { ttlMs: 5_000 },
  userAgent: 'my-app/1.0.0',
});

// Health check
const health = await client.health.check();
console.log('API Status:', health.status);

// List active markets
const markets = await client.markets.list({
  active: true,
  limit: 10,
});

// Get market details with normalized data
const market = await client.markets.getBySlug('bitcoin-up-or-down-oct-2');
console.log('Outcomes:', market.outcomes); // ['Yes', 'No'] - automatically parsed
console.log('Prices:', market.outcomePrices); // [0.6, 0.4] - automatically parsed

// Search across markets, events, and profiles
const results = await client.search.query({
  q: 'bitcoin',
  types: ['market', 'event'],
  limit: 20,
});

Configuration

Client Options

interface GammaClientConfig {
  baseURL?: string; // Default: 'https://gamma-api.polymarket.com'
  timeoutMs?: number; // Default: 10_000
  retries?: number; // Default: 2
  rateLimit?: {
    // Default: { burst: 5, ratePerSec: 5 }
    burst: number;
    ratePerSec: number;
  };
  cache?: {
    // Default: { ttlMs: 5_000 }
    ttlMs?: number; // Set to 0 to disable caching
  };
  userAgent?: string; // Default: 'gamma-client/1.0.0'
}

Examples

Basic Usage

const client = new GammaClient();

Custom Configuration

const client = new GammaClient({
  baseURL: 'https://gamma-api.polymarket.com',
  timeoutMs: 15_000,
  retries: 3,
  rateLimit: { burst: 10, ratePerSec: 8 },
  cache: { ttlMs: 10_000 },
  userAgent: 'my-trading-bot/1.0.0',
});

No Caching

const client = new GammaClient({
  cache: { ttlMs: 0 },
});

API Reference

Health

client.health.check()

Check the health status of the Gamma API.

Returns: Promise<HealthCheckResponse>

const health = await client.health.check();
// { status: 'healthy', timestamp: '2024-01-01T00:00:00Z', ... }

Sports

client.sports.listTeams(params?)

List all sports teams with optional filtering.

Parameters:

  • params.limit? - Number of teams to return
  • params.offset? - Number of teams to skip
  • params.sport? - Filter by sport
  • params.league? - Filter by league

Returns: Promise<ListTeamsResponse>

const teams = await client.sports.listTeams({
  sport: 'basketball',
  limit: 10,
});

client.sports.getMetadata()

Get sports metadata information.

Returns: Promise<SportsMetadataResponse>

const metadata = await client.sports.getMetadata();
// { sports: [{ id: '1', name: 'Basketball', leagues: [...] }] }

Tags

client.tags.list(params?)

List all tags with optional filtering.

Parameters:

  • params.limit? - Number of tags to return
  • params.offset? - Number of tags to skip
  • params.category? - Filter by category
  • params.search? - Search term

Returns: Promise<ListTagsResponse>

const tags = await client.tags.list({
  category: 'politics',
  limit: 20,
});

client.tags.getById(id)

Get a tag by its ID.

Parameters:

  • id - Tag ID

Returns: Promise<Tag>

const tag = await client.tags.getById('123');

client.tags.getBySlug(slug)

Get a tag by its slug.

Parameters:

  • slug - Tag slug

Returns: Promise<Tag>

const tag = await client.tags.getBySlug('us-elections');

client.tags.getRelationshipsById(id, params?)

Get related tags relationships by tag ID.

Parameters:

  • id - Tag ID
  • params.limit? - Number of relationships to return
  • params.offset? - Number of relationships to skip

Returns: Promise<TagRelationships>

const relationships = await client.tags.getRelationshipsById('123');

client.tags.getRelationshipsBySlug(slug, params?)

Get related tags relationships by tag slug.

Parameters:

  • slug - Tag slug
  • params.limit? - Number of relationships to return
  • params.offset? - Number of relationships to skip

Returns: Promise<TagRelationships>

const relationships = await client.tags.getRelationshipsBySlug('us-elections');

client.tags.getRelatedToId(id, params?)

Get tags related to a tag ID.

Parameters:

  • id - Tag ID
  • params.limit? - Number of related tags to return
  • params.offset? - Number of related tags to skip

Returns: Promise<Tag[]>

const relatedTags = await client.tags.getRelatedToId('123');

client.tags.getRelatedToSlug(slug, params?)

Get tags related to a tag slug.

Parameters:

  • slug - Tag slug
  • params.limit? - Number of related tags to return
  • params.offset? - Number of related tags to skip

Returns: Promise<Tag[]>

const relatedTags = await client.tags.getRelatedToSlug('us-elections');

Events

client.events.list(params?)

List all events with optional filtering.

Parameters:

  • params.limit? - Number of events to return
  • params.offset? - Number of events to skip
  • params.active? - Filter by active status
  • params.category? - Filter by category
  • params.tags? - Filter by tags
  • params.startDate? - Filter by start date
  • params.endDate? - Filter by end date

Returns: Promise<ListEventsResponse>

const events = await client.events.list({
  active: true,
  category: 'politics',
  limit: 50,
});

client.events.getById(id)

Get an event by its ID.

Parameters:

  • id - Event ID

Returns: Promise<Event>

const event = await client.events.getById('123');

client.events.getTags(eventId)

Get tags for an event.

Parameters:

  • eventId - Event ID

Returns: Promise<Tag[]>

const tags = await client.events.getTags('123');

client.events.getBySlug(slug)

Get an event by its slug.

Parameters:

  • slug - Event slug

Returns: Promise<Event>

const event = await client.events.getBySlug('2024-presidential-election');

Markets

client.markets.list(params?)

List all markets with optional filtering.

Parameters:

  • params.limit? - Number of markets to return
  • params.offset? - Number of markets to skip
  • params.active? - Filter by active status
  • params.eventId? - Filter by event ID
  • params.category? - Filter by category
  • params.tags? - Filter by tags

Returns: Promise<ListMarketsResponse>

const markets = await client.markets.list({
  active: true,
  limit: 100,
});

client.markets.getById(id)

Get a market by its ID.

Parameters:

  • id - Market ID

Returns: Promise<Market>

const market = await client.markets.getById('123');

client.markets.getTags(marketId)

Get tags for a market.

Parameters:

  • marketId - Market ID

Returns: Promise<Tag[]>

const tags = await client.markets.getTags('123');

client.markets.getBySlug(slug)

Get a market by its slug.

Parameters:

  • slug - Market slug

Returns: Promise<Market>

const market = await client.markets.getBySlug('bitcoin-up-or-down-oct-2');

Series

client.series.list(params?)

List all series with optional filtering.

Parameters:

  • params.limit? - Number of series to return
  • params.offset? - Number of series to skip
  • params.active? - Filter by active status
  • params.category? - Filter by category

Returns: Promise<ListSeriesResponse>

const series = await client.series.list({
  active: true,
  limit: 20,
});

client.series.getById(id)

Get a series by its ID.

Parameters:

  • id - Series ID

Returns: Promise<Series>

const series = await client.series.getById('123');

Comments

client.comments.list(params?)

List all comments with optional filtering.

Parameters:

  • params.limit? - Number of comments to return
  • params.offset? - Number of comments to skip
  • params.marketId? - Filter by market ID
  • params.eventId? - Filter by event ID
  • params.parentId? - Filter by parent comment ID

Returns: Promise<ListCommentsResponse>

const comments = await client.comments.list({
  marketId: '123',
  limit: 50,
});

client.comments.getById(id)

Get a comment by its ID.

Parameters:

  • id - Comment ID

Returns: Promise<Comment>

const comment = await client.comments.getById('123');

client.comments.getByUserAddress(address, params?)

Get comments by user address.

Parameters:

  • address - User address
  • params.limit? - Number of comments to return
  • params.offset? - Number of comments to skip

Returns: Promise<ListCommentsResponse>

const comments = await client.comments.getByUserAddress('0x123...', {
  limit: 20,
});

Search

client.search.query(params)

Search markets, events, and profiles.

Parameters:

  • params.q - Search query (required)
  • params.limit? - Number of results to return
  • params.offset? - Number of results to skip
  • params.types? - Filter by result types
  • params.category? - Filter by category
  • params.tags? - Filter by tags

Returns: Promise<SearchResponse>

const results = await client.search.query({
  q: 'bitcoin',
  types: ['market', 'event'],
  limit: 20,
});

Data Normalization

The Gamma API returns some fields as JSON-encoded strings. The client automatically normalizes these fields:

Market Data

const market = await client.markets.getById('123');

// These fields are automatically parsed from JSON strings:
console.log(market.outcomes); // ['Yes', 'No'] instead of '["Yes", "No"]'
console.log(market.outcomePrices); // [0.6, 0.4] instead of '[0.6, 0.4]'
console.log(market.clobTokenIds); // ['token1', 'token2'] instead of '["token1", "token2"]'

Manual Normalization

You can also use the normalization utilities directly:

import { parseJsonArray, toNumber, toNumberArray, toStringArray } from '@codifydoo/gamma-client';

const jsonString = '["a", "b", "c"]';
const parsed = parseJsonArray(jsonString); // ['a', 'b', 'c']

const numberString = '123.45';
const number = toNumber(numberString); // 123.45

const numberArrayString = '[1, 2, 3]';
const numbers = toNumberArray(numberArrayString); // [1, 2, 3]

Pagination

The client supports both offset-based and cursor-based pagination:

Offset Pagination

// Get first page
const page1 = await client.markets.list({ limit: 10, offset: 0 });

// Get second page
const page2 = await client.markets.list({ limit: 10, offset: 10 });

// Check if there are more results
if (page1.hasMore) {
  console.log('More results available');
}

Cursor Pagination

// Get first page
const page1 = await client.events.list({ limit: 10 });

// Get next page using cursor
if (page1.nextCursor) {
  const page2 = await client.events.list({
    limit: 10,
    cursor: page1.nextCursor,
  });
}

Error Handling

The client provides comprehensive error handling:

import { GammaClientError } from '@codifydoo/gamma-client';

try {
  const market = await client.markets.getById('invalid-id');
} catch (error) {
  if (error instanceof GammaClientError) {
    console.error('API Error:', error.message);
    console.error('Status Code:', error.statusCode);
    console.error('Endpoint:', error.endpoint);
  } else {
    console.error('Unexpected error:', error);
  }
}

Common Error Scenarios

Network Errors

try {
  const result = await client.markets.list();
} catch (error) {
  // Network errors are automatically retried with exponential backoff
  console.error('Request failed after retries:', error.message);
}

Validation Errors

try {
  const result = await client.markets.list({ limit: -1 }); // Invalid limit
} catch (error) {
  // Zod validation error
  console.error('Validation error:', error.message);
}

Rate Limiting

// The client automatically handles rate limiting
// Requests are queued and executed at the configured rate
const promises = Array(100)
  .fill(null)
  .map(() => client.markets.list());
await Promise.all(promises); // Will be rate-limited automatically

Caching

The client includes an optional in-memory cache:

const client = new GammaClient({
  cache: { ttlMs: 10_000 }, // Cache for 10 seconds
});

// First call - hits API
const market1 = await client.markets.getById('123');

// Second call within 10 seconds - hits cache
const market2 = await client.markets.getById('123');

// Clear cache
client.clearCache();

// Get cache statistics
const stats = client.getCacheStats();
console.log('Cache size:', stats?.size);

Rate Limiting

The client implements a token bucket rate limiter:

const client = new GammaClient({
  rateLimit: {
    burst: 10, // Allow up to 10 requests immediately
    ratePerSec: 5, // Then limit to 5 requests per second
  },
});

// These requests will be rate-limited automatically
const promises = Array(20)
  .fill(null)
  .map(() => client.markets.list());
await Promise.all(promises);

Best Practices

1. Error Handling

Always wrap API calls in try-catch blocks:

try {
  const result = await client.markets.list();
  // Process result
} catch (error) {
  // Handle error appropriately
  console.error('Failed to fetch markets:', error.message);
}

2. Pagination

Use pagination to avoid loading too much data at once:

async function getAllMarkets() {
  const allMarkets = [];
  let offset = 0;
  const limit = 100;

  while (true) {
    const response = await client.markets.list({ limit, offset });
    allMarkets.push(...response.data);

    if (!response.hasMore) break;
    offset += limit;
  }

  return allMarkets;
}

3. Caching

Enable caching for frequently accessed data:

const client = new GammaClient({
  cache: { ttlMs: 30_000 }, // Cache for 30 seconds
});

4. Rate Limiting

Configure appropriate rate limits for your use case:

const client = new GammaClient({
  rateLimit: {
    burst: 5, // Conservative burst
    ratePerSec: 2, // Conservative rate
  },
});

5. Type Safety

Use TypeScript strict mode and leverage the provided types:

import { Market, ListMarketsRequest } from '@codifydoo/gamma-client';

async function processMarkets(params: ListMarketsRequest): Promise<Market[]> {
  const response = await client.markets.list(params);
  return response.data;
}

Troubleshooting

Common Issues

1. Network Timeouts

const client = new GammaClient({
  timeoutMs: 30_000, // Increase timeout for slow connections
});

2. Rate Limiting

const client = new GammaClient({
  rateLimit: {
    burst: 1, // Reduce burst
    ratePerSec: 1, // Reduce rate
  },
});

3. Memory Usage

const client = new GammaClient({
  cache: { ttlMs: 0 }, // Disable caching to reduce memory usage
});

4. Validation Errors

Check the error message for specific validation issues:

try {
  await client.markets.list({ limit: -1 });
} catch (error) {
  console.error('Validation error:', error.message);
  // Look for specific field validation errors
}

Debug Mode

Enable debug logging to see request details:

// The client logs requests at debug level
// Enable debug logging in your application

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

License

MIT License - see LICENSE file for details.

Support