Skip to main content

Fan SDK

Drop in. Fan graph included.

The official TypeScript/JavaScript SDK for revolution.fan. Works in browser, SSR, React Native, and Node.js. One import gives you verified fan identity, $FAN balance, attendance history, and real-time event context.

TypeScriptReact NativeNode.jsREST

Not yet published

The SDKs are not on npm or PyPI yet. The source is in the monorepo (packages/sdk, sdks/python) and you can build and link it locally, but a registry install will 404. The reference below describes the real, current method surface, no placeholder endpoints. Email sdk@revolution.fan if you want early access.

Installation

bash
# Not published to npm yet, build from the monorepo:
git clone https://github.com/tokenevents/revolution-fan
cd revolution-fan/packages/sdk && npm install && npm run build

# When it ships, the package name will be:
#   npm install @revolution-fan/sdk

Initialisation

typescript
import { Revolution } from '@revolution-fan/sdk';

const rev = new Revolution({
  apiKey: 'rev_live_xxxx',       // required, get yours at revolution.fan/developers
  baseUrl: 'https://api.revolution.fan/api/v1', // default shown
  defaultRegion: 'atx',          // optional, pre-fills region on all queries
  timeout: 10_000,               // optional, ms (default 10 000)
  authScheme: 'bearer',          // optional, see Auth docs
});

Events

Discover, search, and retrieve live events. Available on all key tiers.

List events

typescript
const { items, total, hasMore } = await rev.events.list({
  region: 'atx',           // required, region slug
  dateFrom: '2026-05-01',  // ISO date
  dateTo: '2026-05-31',
  genre: 'hip-hop',        // optional filter
  featured: true,          // only featured events
  page: 1,
  pageSize: 20,
});

Get a single event

typescript
const event = await rev.events.get('khruangbin-stubbs-2026-05-14');

console.log(event.title);       // "Khruangbin at Stubb's"
console.log(event.date);        // "2026-05-14T21:00:00-05:00"
console.log(event.venue.name);  // "Stubb's Outdoor Amphitheater"
console.log(event.ticketUrl);   // "https://..."
console.log(event.imageUrl);    // hero image

Today & tomorrow feed

typescript
const region = await rev.regions.nearest(lat, lng);
const { today, tomorrow } = await rev.events.todayTomorrow(region.slug);

Create an open event

Any authenticated user can create a public event in seconds, no venue account required. Ideal for conference side events, community meetups, birthday parties, and anything in between. Every attendee who scans in still earns $FAN and gets a verified attendance record.

typescript
// POST /api/v1/events/quick, requires a valid user Bearer token
const { event } = await rev.events.create({
  title: 'DeFi Happy Hour @ Consensus',  // required
  startTime: '2026-05-23T18:00:00-05:00', // required (ISO 8601)
  endTime: '2026-05-23T21:00:00-05:00',  // optional
  locationText: 'The Rusty Nail, Austin TX', // free-text, or "Online"
  description: 'Side event for Consensus attendees. Drinks on us.',
  isFree: true,                           // default true
  ticketPrice: undefined,                 // number (USD) when isFree=false
  imageUrl: 'https://...',               // optional hero image
});

console.log(event.slug);       // auto-generated from title + date
console.log(event.eventType);  // "open_event"
// redirect user to: /events/{event.slug}

Venues & Artists

typescript
// Venue profile + upcoming shows
const venue = await rev.venues.get('stubbs-austin');
const shows = await rev.venues.events('stubbs-austin', 10);

// Artist profile + upcoming dates
const artist = await rev.artists.get('khruangbin');
const tour   = await rev.artists.events('khruangbin', 20);

Marketplace

Manage recurring data subscriptions. Requires a Marketplace key (mk_live_…) with authScheme: 'marketplace'. One-off queries are Python-only today, see the Python section below.

typescript
const rev = new Revolution({ apiKey: 'mk_live_xxxx', authScheme: 'marketplace' });

// What would a subscription cost?
const quote = await rev.marketplace.estimate({
  dataProviderId: 'dp_123',
  dataType: 'fan_demographics',
  billingPeriod: 'monthly',
});

// Create it, then manage it
const sub = await rev.marketplace.create({
  dataProviderId: 'dp_123',
  dataType: 'fan_demographics',
  billingPeriod: 'monthly',
});
const { items } = await rev.marketplace.list({ page: 1, pageSize: 20 });
await rev.marketplace.cancel(sub.id);

Attendance

Venue check-in and attendance proofs. Requires a Scanner key.

typescript
const rev = new Revolution({ apiKey: 'scan_xxxx', authScheme: 'scanner' });

// Check a fan in
const result = await rev.attendance.checkin({
  rfidTag: 'TAG_ABC123',
  eventId: 1042,
  venueName: "Stubb's Bar-B-Q",
  checkInAt: new Date().toISOString(),
});

// Look up an existing proof
const proof = await rev.attendance.verify('proof_xyz789');

Embed Widget

Drop a self-contained event listing into any HTML page, no framework required.

html
<!-- Add to any website -->
<div id="events"></div>
<script src="https://cdn.revolution.fan/sdk/embed.js"></script>
<script>
  RevolutionEmbed.mount('#events', {
    apiKey: 'rev_live_xxxx',
    region: 'atx',
    theme: 'dark',
    maxEvents: 6,
    onTicketClick: (event) => {
      // Handle ticket purchase in your own UI
    },
  });
</script>

Error Handling

typescript
import { RevolutionError } from '@revolution-fan/sdk';

try {
  const event = await rev.events.get('non-existent-slug');
} catch (err) {
  if (err instanceof RevolutionError) {
    console.log(err.status);   // 404
    console.log(err.code);     // 'EVENT_NOT_FOUND'
    console.log(err.message);  // human-readable
  }
}

Python SDK

The official Python client for revolution.fan. Designed for data science workflows, analytics pipelines, and backend services. Works with Pandas, Jupyter, and any Python 3.8+ environment.

Python 3.8+JupyterPandasAsync

Installation

bash
# Not on PyPI yet, install from the monorepo:
git clone https://github.com/tokenevents/revolution-fan
pip install -e revolution-fan/sdks/python

Initialisation

The Python client covers the Data Marketplace only, there is no events, venues, or artists namespace on it. Use the TypeScript SDK or the REST API for those.

python
from revolution_fan import MarketplaceClient

client = MarketplaceClient(
    api_key="mk_live_xxxx",   # or set REVOLUTION_FAN_API_KEY
    base_url="https://api.revolution.fan/api/v1/marketplace",
    timeout=30,
)

Data Marketplace

python
# Browse what's licensable
catalog = client.get_catalog()

# Preview, free, returns the match count and the price
preview = client.preview_query(
    filters=[
        {"key": "top_genres",            "operator": "contains", "value": "hip-hop"},
        {"key": "concerts_attended_12m", "operator": "gte",      "value": "3"},
        {"key": "city",                  "operator": "eq",       "value": "Los Angeles"},
    ],
    attributes=["top_genres", "events_attended_rfan", "average_ticket_spend"],
    query_type="aggregated",
)

print(preview.result_count)   # fans matched
print(preview.price_usd)      # what executing it will cost

# Execute, charges your account. query_id is an int.
result = client.execute_query(preview.query_id, delivery_format="json")
print(result.data)

Sandbox Mode

python
# Synthetic data, no API key, nothing charged.
from revolution_fan import SandboxClient

client = SandboxClient()

preview = client.preview_query(
    filters=[{"key": "top_genres", "operator": "contains", "value": "hip-hop"}],
    attributes=["top_genres", "spend_band"],
    query_type="aggregated",
)
# Safe to use in notebooks and CI

Jupyter Notebooks

Four sample notebooks are included in the repo under notebooks/ covering genre affinity segmentation, concert attendance lookalike modelling, cross-vertical fan profiles, and esports sponsor targeting.

bash
# Clone and run locally
git clone https://github.com/tokenevents/revolution-fan
cd revolution-fan/notebooks
jupyter notebook

Error Handling (Python)

python
from revolution_fan import MarketplaceError, AuthError, RateLimitError

try:
    result = client.execute_query(1234)
except AuthError:
    print("Invalid or expired API key")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s")
except MarketplaceError as e:
    print(f"API error: {e}")