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

# SDK Reference

> Complete reference for the ticketnation-sdk TypeScript package.

## Installation

```bash theme={null}
npm install ticketnation-sdk
```

Requires Node.js 18+ (uses native `fetch`). TypeScript 5.0+ recommended.

<Info>
  Current version: **v1.1.1** — [view on npm](https://www.npmjs.com/package/ticketnation-sdk)
</Info>

## Initialization

```typescript theme={null}
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
});
```

<Warning>
  **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.
</Warning>

***

## tn.me()

Get API key and organization info.

```typescript theme={null}
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.

```typescript theme={null}
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()`.

```typescript theme={null}
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'
```

<Tip>
  Use `createAndPublish()` when you want events to go live immediately. Use `create()` + `publish()` separately when you need a review step before going live.
</Tip>

### list(params?)

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

### get(idOrSlug)

```typescript theme={null}
const event = await tn.events.get('summer-fest-2025');
// or
const event = await tn.events.get('uuid-event-id');
// Returns: Event
```

### update(eventId, params)

```typescript theme={null}
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)

```typescript theme={null}
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.

```typescript theme={null}
const result = await tn.events.delete(eventId);
// Returns: { deleted: true, id: 'uuid' }
```

***

## tn.tickets

### create(eventId, params)

```typescript theme={null}
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)

```typescript theme={null}
const tickets = await tn.tickets.list(eventId);
// Returns: Ticket[]
```

### get(eventId, ticketId)

```typescript theme={null}
const ticket = await tn.tickets.get(eventId, ticketId);
// Returns: Ticket
```

### update(eventId, ticketId, params)

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

### publish(eventId, ticketId)

```typescript theme={null}
const ticket = await tn.tickets.publish(eventId, ticketId);
// Returns: Ticket
```

### markSoldOut(eventId, ticketId)

Sets `remainingQuantity` to 0.

```typescript theme={null}
const ticket = await tn.tickets.markSoldOut(eventId, ticketId);
// Returns: Ticket (with remainingQuantity: 0)
```

### delete(eventId, ticketId)

Only works if no tickets have been sold.

```typescript theme={null}
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)

```typescript theme={null}
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)

```typescript theme={null}
const performers = await tn.performers.list(eventId);
// Returns: Performer[]
```

### remove(eventId, performerId)

```typescript theme={null}
const result = await tn.performers.remove(eventId, performerId);
// Returns: { deleted: true, id: 'uuid' }
```

**Full example — building a lineup:**

```typescript theme={null}
// 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)

```typescript theme={null}
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)

```typescript theme={null}
const schedule = await tn.schedules.list(eventId);
// Returns: Schedule[]
```

### update(eventId, scheduleId, params)

```typescript theme={null}
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)

```typescript theme={null}
const result = await tn.schedules.remove(eventId, scheduleId);
// Returns: { deleted: true, id: 'uuid' }
```

**Full example — building a timetable:**

```typescript theme={null}
// 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)

```typescript theme={null}
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)

```typescript theme={null}
const brands = await tn.brands.list(eventId);
// Returns: Brand[]
```

### remove(eventId, brandId)

```typescript theme={null}
const result = await tn.brands.remove(eventId, brandId);
// Returns: { deleted: true, id: 'uuid' }
```

**Full example — attaching sponsors:**

```typescript theme={null}
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?)

```typescript theme={null}
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.

```typescript theme={null}
const order = await tn.orders.get(orderId);
// Returns: Order (with payment info)
```

***

## tn.venues

### search(params)

```typescript theme={null}
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.

```typescript theme={null}
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()

```typescript theme={null}
const webhooks = await tn.webhooks.list();
// Returns: Webhook[]
```

### update(webhookId, params)

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

### delete(webhookId)

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

### test(webhookId)

Sends a test payload to your webhook URL.

```typescript theme={null}
const result = await tn.webhooks.test(webhookId);
// Returns: { success: true, statusCode: 200, message: '...' }
```

### deliveries(webhookId, params?)

View delivery history for a webhook.

```typescript theme={null}
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.

```typescript theme={null}
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.

```typescript theme={null}
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:

```typescript theme={null}
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:

```typescript theme={null}
import { fetchAllPages } from 'ticketnation-sdk';

const allEvents = await fetchAllPages((p) => tn.events.list(p));
console.log(`Total: ${allEvents.length} events`);
```

<Warning>
  `fetchAllPages()` loads everything into memory. For large datasets, prefer `paginate()` which streams one page at a time.
</Warning>

***

## Error Handling

All API errors throw `TicketnationError` with a `hint` property that provides actionable guidance:

```typescript theme={null}
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.'
  }
}
```

<Tip>
  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.
</Tip>

**Error handling with hints:**

```typescript theme={null}
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](/developers/errors) page for the complete list of error codes and troubleshooting tips.

***

## TypeScript Types

All types are exported from the package:

```typescript theme={null}
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

```typescript theme={null}
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;
}
```
