Skip to main content

Installation

npm install ticketnation-sdk
Requires Node.js 18+ (uses native fetch). TypeScript 5.0+ recommended.
Current version: v1.1.1view on npm

Initialization

import { Ticketnation } from 'ticketnation-sdk';

const tn = new Ticketnation({
  apiKey: process.env.TICKETNATION_API_KEY!,  // Required — never hardcode!
  baseUrl: 'http://localhost:4000',  // Default: https://api.ticketnation.ph
  timeout: 30000,                    // Default: 30s
  retries: 2,                        // Default: 2 retries on 5xx
  debug: false,                      // Logs requests with redacted key
});
Never hardcode your API key. Store it in an environment variable (TICKETNATION_API_KEY) and load it at runtime. Add .env to your .gitignore to prevent accidental commits.

tn.me()

Get API key and organization info.
const info = await tn.me();
// Returns: AccountInfo
// {
//   apiKey: { id, name, scopes, callbackUrl, createdAt, expiresAt, lastUsedAt },
//   organization: { id, name, slug }
// }

tn.events

create(params)

Creates an event in DRAFT status. Optionally include inline ticket types.
const event = await tn.events.create({
  name: 'Summer Fest',                    // required
  dateTime: '2025-06-15T18:00:00.000Z',  // required
  endDateTime: '2025-06-15T23:00:00.000Z',
  venueId: 'uuid',
  type: 'PAID',                           // 'PAID' | 'FREE'
  journeyType: 'STANDARD',               // 'STANDARD' | 'RSVP' | 'PRESELLING'
  visibility: 'PUBLIC',                   // 'PUBLIC' | 'PRIVATE'
  imageUrl: 'https://example.com/cover.jpg',
  galleryUrls: [
    'https://example.com/gallery-1.jpg',
    'https://example.com/gallery-2.jpg',
  ],
  absorbFees: true,                       // default: true
  timezone: 'Asia/Manila',               // default: 'Asia/Manila'
  currency: 'PHP',                        // default: 'PHP'
  eventCapacity: 1000,
  callbackUrl: 'https://api.example.com/webhooks',
  tickets: [                              // optional inline tickets
    { name: 'GA', price: 1500, quantity: 500, published: true },
  ],
});
// Returns: Event (status: 'DRAFT')

createAndPublish(params)

Creates an event and immediately publishes it to the marketplace in a single call. Accepts the same parameters as create().
const event = await tn.events.createAndPublish({
  name: 'Summer Fest',
  dateTime: '2025-06-15T18:00:00.000Z',
  tickets: [
    { name: 'GA', price: 1500, quantity: 500, published: true },
  ],
});
// Returns: Event (status: 'PUBLISHED')
console.log(event.status); // 'PUBLISHED'
Use createAndPublish() when you want events to go live immediately. Use create() + publish() separately when you need a review step before going live.

list(params?)

const { data, meta } = await tn.events.list({
  page: 1,
  take: 10,
  status: 'PUBLISHED',   // 'DRAFT' | 'PUBLISHED' | 'ARCHIVED'
  search: 'summer',
});
// Returns: PaginatedResponse<Event>

get(idOrSlug)

const event = await tn.events.get('summer-fest-2025');
// or
const event = await tn.events.get('uuid-event-id');
// Returns: Event

update(eventId, params)

const event = await tn.events.update(eventId, {
  name: 'Updated Name',
  eventCapacity: 2000,
  imageUrl: 'https://example.com/new-cover.jpg',
  galleryUrls: ['https://example.com/new-gallery.jpg'],
});
// Returns: Event

publish(eventId) / unpublish(eventId) / archive(eventId)

const event = await tn.events.publish(eventId);
const event = await tn.events.unpublish(eventId);
const event = await tn.events.archive(eventId);
// Returns: Event

delete(eventId)

Only works on DRAFT events with no sold tickets.
const result = await tn.events.delete(eventId);
// Returns: { deleted: true, id: 'uuid' }

tn.tickets

create(eventId, params)

const ticket = await tn.tickets.create(eventId, {
  name: 'VIP Pass',        // required
  price: 5000,             // required, in whole pesos (₱5,000.00)
  quantity: 100,           // required
  section: 'VIP Section',
  row: 'A',
  type: 'VIP',            // 'GENERAL_ADMISSION' | 'RESERVED_SEAT' | 'VIP'
  maximumPurchaseQuantity: 4,
  published: true,
});
// Returns: Ticket

list(eventId)

const tickets = await tn.tickets.list(eventId);
// Returns: Ticket[]

get(eventId, ticketId)

const ticket = await tn.tickets.get(eventId, ticketId);
// Returns: Ticket

update(eventId, ticketId, params)

const ticket = await tn.tickets.update(eventId, ticketId, {
  price: 4500,
  quantity: 150,
});
// Returns: Ticket

publish(eventId, ticketId)

const ticket = await tn.tickets.publish(eventId, ticketId);
// Returns: Ticket

markSoldOut(eventId, ticketId)

Sets remainingQuantity to 0.
const ticket = await tn.tickets.markSoldOut(eventId, ticketId);
// Returns: Ticket (with remainingQuantity: 0)

delete(eventId, ticketId)

Only works if no tickets have been sold.
const result = await tn.tickets.delete(eventId, ticketId);
// Returns: { deleted: true, id: 'uuid' }

tn.performers

Manage the performer lineup for an event. Requires events:write scope for mutations, events:read for listing.

create(eventId, params)

const performer = await tn.performers.create(eventId, {
  name: 'SB19',                               // required
  type: 'ARTIST',                             // optional
  imageUrl: 'https://example.com/sb19.jpg',   // optional
  description: 'P-pop icons',                 // optional
});
// Returns: Performer
// { id, name, type, imageUrl, description, eventId, createdAt }

list(eventId)

const performers = await tn.performers.list(eventId);
// Returns: Performer[]

remove(eventId, performerId)

const result = await tn.performers.remove(eventId, performerId);
// Returns: { deleted: true, id: 'uuid' }
Full example — building a lineup:
// Add all performers
const headliner = await tn.performers.create(eventId, {
  name: 'SB19',
  type: 'ARTIST',
  imageUrl: 'https://example.com/sb19.jpg',
  description: 'P-pop icons',
});

const dj = await tn.performers.create(eventId, {
  name: 'DJ Nix',
  type: 'DJ',
});

const host = await tn.performers.create(eventId, {
  name: 'Vice Ganda',
  type: 'HOST',
  description: 'Event host and comedian',
});

// List the lineup
const lineup = await tn.performers.list(eventId);
console.log(`${lineup.length} performers on the bill`);

// Remove a performer if plans change
await tn.performers.remove(eventId, dj.id);

tn.schedules

Build a timetable for your event. Schedule entries can optionally link to performers. Requires events:write scope for mutations, events:read for listing.

create(eventId, params)

const entry = await tn.schedules.create(eventId, {
  title: 'SB19 Live',                          // required
  startTime: '2025-06-15T20:00:00.000Z',       // required
  endTime: '2025-06-15T22:30:00.000Z',         // required
  description: 'Main stage performance',       // optional
  icon: 'microphone',                           // optional
  color: '#1DB954',                             // optional
  performerId: 'uuid-performer-id',            // optional
});
// Returns: Schedule
// { id, title, startTime, endTime, description, icon, color, performerId, eventId, createdAt }

list(eventId)

const schedule = await tn.schedules.list(eventId);
// Returns: Schedule[]

update(eventId, scheduleId, params)

const entry = await tn.schedules.update(eventId, scheduleId, {
  title: 'SB19 Main Set (Extended)',
  endTime: '2025-06-15T23:00:00.000Z',
});
// Returns: Schedule

remove(eventId, scheduleId)

const result = await tn.schedules.remove(eventId, scheduleId);
// Returns: { deleted: true, id: 'uuid' }
Full example — building a timetable:
// Create performers first
const sb19 = await tn.performers.create(eventId, {
  name: 'SB19',
  type: 'ARTIST',
});

const djNix = await tn.performers.create(eventId, {
  name: 'DJ Nix',
  type: 'DJ',
});

// Build the schedule
await tn.schedules.create(eventId, {
  title: 'Doors Open',
  startTime: '2025-06-15T17:00:00.000Z',
  endTime: '2025-06-15T18:00:00.000Z',
  icon: 'door',
});

await tn.schedules.create(eventId, {
  title: 'DJ Nix Warm-Up Set',
  startTime: '2025-06-15T18:00:00.000Z',
  endTime: '2025-06-15T19:30:00.000Z',
  performerId: djNix.id,
  color: '#FF6B35',
});

await tn.schedules.create(eventId, {
  title: 'SB19 Live',
  startTime: '2025-06-15T20:00:00.000Z',
  endTime: '2025-06-15T22:30:00.000Z',
  performerId: sb19.id,
  description: 'Main stage headline set',
  color: '#1DB954',
});

// Update if timing changes
const schedule = await tn.schedules.list(eventId);
const sb19Set = schedule.find((s) => s.title === 'SB19 Live');
if (sb19Set) {
  await tn.schedules.update(eventId, sb19Set.id, {
    endTime: '2025-06-15T23:00:00.000Z',
  });
}

tn.brands

Attach sponsor or partner brands to your event. Requires events:write scope for mutations, events:read for listing.

create(eventId, params)

const brand = await tn.brands.create(eventId, {
  name: 'Red Bull',                              // required
  url: 'https://redbull.com',                   // optional
  imageUrl: 'https://example.com/redbull.png',  // optional
  description: 'Energy drink partner',          // optional
});
// Returns: Brand
// { id, name, url, imageUrl, description, eventId, createdAt }

list(eventId)

const brands = await tn.brands.list(eventId);
// Returns: Brand[]

remove(eventId, brandId)

const result = await tn.brands.remove(eventId, brandId);
// Returns: { deleted: true, id: 'uuid' }
Full example — attaching sponsors:
await tn.brands.create(eventId, {
  name: 'Red Bull',
  url: 'https://redbull.com',
  imageUrl: 'https://example.com/redbull.png',
  description: 'Energy drink partner',
});

await tn.brands.create(eventId, {
  name: 'Globe Telecom',
  url: 'https://globe.com.ph',
  imageUrl: 'https://example.com/globe.png',
  description: 'Presenting sponsor',
});

await tn.brands.create(eventId, {
  name: 'Jollibee',
  imageUrl: 'https://example.com/jollibee.png',
  description: 'Official food partner',
});

// List all brands
const brands = await tn.brands.list(eventId);
console.log(`${brands.length} sponsors attached`);

tn.orders

Orders are read-only. Requires orders:read scope.

list(eventId, params?)

const { data, meta } = await tn.orders.list(eventId, {
  page: 1,
  take: 20,
  status: 'COMPLETED',  // 'PENDING' | 'COMPLETED' | 'CANCELLED' | 'REFUNDED'
});
// Returns: PaginatedResponse<Order>

get(orderId)

Includes payment details.
const order = await tn.orders.get(orderId);
// Returns: Order (with payment info)

tn.venues

search(params)

const { data, meta } = await tn.venues.search({
  query: 'MOA Arena',  // required
  page: 1,
  take: 10,
});
// Returns: PaginatedResponse<Venue>

tn.webhooks

create(params)

Returns the webhook with a secret field — store it securely, it is only shown once.
const webhook = await tn.webhooks.create({
  url: 'https://api.example.com/webhooks/ticketnation',
  events: ['order.completed', 'event.sold_out'],
});
console.log(webhook.secret); // whsec_...
// Returns: WebhookWithSecret

list()

const webhooks = await tn.webhooks.list();
// Returns: Webhook[]

update(webhookId, params)

const webhook = await tn.webhooks.update(webhookId, {
  events: ['order.completed'],
  isActive: true,
});
// Returns: Webhook

delete(webhookId)

const result = await tn.webhooks.delete(webhookId);
// Returns: { deleted: true, id: 'uuid' }

test(webhookId)

Sends a test payload to your webhook URL.
const result = await tn.webhooks.test(webhookId);
// Returns: { success: true, statusCode: 200, message: '...' }

deliveries(webhookId, params?)

View delivery history for a webhook.
const { data, meta } = await tn.webhooks.deliveries(webhookId, {
  page: 1,
  take: 20,
});
// Returns: PaginatedResponse<WebhookDelivery>

Utilities

The SDK exports helper functions for common tasks.

formatPeso(amount)

Formats a number as a Philippine Peso string. Returns "Free" for zero.
import { formatPeso } from 'ticketnation-sdk';

formatPeso(1500);  // "₱1,500.00"
formatPeso(0);     // "Free"
formatPeso(99);    // "₱99.00"

validatePrice(price)

Validates that a price is a valid number. Throws a TicketnationError if invalid.
import { validatePrice } from 'ticketnation-sdk';

validatePrice(1500);   // OK — no error
validatePrice(-100);   // Throws TicketnationError
validatePrice(NaN);    // Throws TicketnationError

Pagination Helpers

paginate()

Async generator that yields one page at a time:
import { paginate } from 'ticketnation-sdk';

for await (const batch of paginate((p) => tn.events.list(p))) {
  for (const event of batch) {
    console.log(event.name);
  }
}

fetchAllPages()

Collects all pages into a single array:
import { fetchAllPages } from 'ticketnation-sdk';

const allEvents = await fetchAllPages((p) => tn.events.list(p));
console.log(`Total: ${allEvents.length} events`);
fetchAllPages() loads everything into memory. For large datasets, prefer paginate() which streams one page at a time.

Error Handling

All API errors throw TicketnationError with a hint property that provides actionable guidance:
import { TicketnationError } from 'ticketnation-sdk';

try {
  await tn.events.get('nonexistent');
} catch (error) {
  if (error instanceof TicketnationError) {
    error.code;      // 'NOT_FOUND'
    error.status;    // 404
    error.message;   // 'Event not found: nonexistent'
    error.requestId; // 'req_a1b2c3d4' — for support tickets
    error.details;   // Array of field errors (for VALIDATION_ERROR)
    error.hint;      // 'Check that the event ID is correct and belongs to your organization.'
  }
}
The error.hint property gives you a human-readable suggestion for how to fix the error. It is especially useful for SCOPE_REQUIRED and VALIDATION_ERROR responses.
Error handling with hints:
try {
  await tn.events.create({ name: '' });
} catch (error) {
  if (error instanceof TicketnationError) {
    console.log(`Error: ${error.message}`);
    if (error.hint) {
      console.log(`Hint: ${error.hint}`);
      // e.g., "The 'name' field is required and cannot be empty."
    }
    if (error.details) {
      console.log('Field errors:', error.details);
    }
  }
}
See the Error Handling page for the complete list of error codes and troubleshooting tips.

TypeScript Types

All types are exported from the package:
import type {
  // Core resources
  Event,
  Ticket,
  Order,
  Venue,
  Performer,
  Schedule,
  Brand,
  Webhook,
  WebhookWithSecret,
  WebhookDelivery,
  WebhookTestResult,
  AccountInfo,
  DeletedResponse,

  // Create/update params
  CreateEventParams,
  CreateTicketParams,
  CreateWebhookParams,
  UpdateWebhookParams,
  CreatePerformerParams,
  CreateScheduleParams,
  UpdateScheduleParams,
  CreateBrandParams,

  // List/search params
  ListEventsParams,
  ListOrdersParams,
  SearchVenuesParams,

  // Pagination
  PaginatedResponse,

  // Config and errors
  TicketnationConfig,
  TicketnationError,
} from 'ticketnation-sdk';

Key Type Definitions

interface CreateEventParams {
  name: string;                                    // required
  dateTime: string;                                // required, ISO 8601
  endDateTime?: string;
  type?: 'PAID' | 'FREE';
  journeyType?: 'STANDARD' | 'RSVP' | 'PRESELLING';
  venueId?: string;
  imageUrl?: string;
  galleryUrls?: string[];
  absorbFees?: boolean;                            // default: true
  timezone?: string;                               // default: 'Asia/Manila'
  currency?: string;                               // default: 'PHP'
  visibility?: 'PUBLIC' | 'PRIVATE';
  callbackUrl?: string;
  eventCapacity?: number;
  description?: string;
  tickets?: CreateTicketParams[];
}

interface CreatePerformerParams {
  name: string;                                    // required
  type?: string;
  imageUrl?: string;
  description?: string;
}

interface CreateScheduleParams {
  title: string;                                   // required
  startTime: string;                               // required, ISO 8601
  endTime: string;                                 // required, ISO 8601
  description?: string;
  icon?: string;
  color?: string;
  performerId?: string;
}

interface CreateBrandParams {
  name: string;                                    // required
  url?: string;
  imageUrl?: string;
  description?: string;
}