NEW Introducing queue management & fraud detection — read the announcement →

Build with Tickitz
API reference & guides

Everything you need to integrate event ticketing, queue management, QR check-in, and fraud detection into your app.

Introduction #

Tickitz is a REST API that gives you every primitive needed to build production-grade event ticketing — from creating events and issuing tickets, to managing high-demand queues and scanning QR codes at the door.

The base URL for all requests:

BASE URL
https://api.tickitz.io/v1

All requests must use HTTPS. Responses are JSON.

New to Tickitz?

Skip to Quickstart to have a live event issuing tickets in under 5 minutes. No credit card required on the free tier.

Quickstart #

Go from zero to a live event with tickets issuing in four steps.

  1. 1
    Install the SDK
    shell
    npm install @tickitz/sdk        # Node.js / TypeScript
    pip install tickitz              # Python
    go get github.com/tickitz/sdk-go # Go
  2. 2
    Initialise the client Store your API key in an environment variable — never hard-code it.
    quickstart.ts
    import { Tickitz } from "@tickitz/sdk";
    
    const tickitz = new Tickitz({
      apiKey: process.env.TICKITZ_API_KEY,
    });
  3. 3
    Create and publish an event
    create-event.ts
    const event = await tickitz.events.create({
      title:       "Summer Music Festival",
      startsAt:    "2025-07-15T18:00:00Z",
      tiers: [
        { name: "General Admission", price: 4999, quantity: 500 },
        { name: "VIP",               price: 14999, quantity: 50  },
      ],
      maxCapacity: 550,
    });
    
    await tickitz.events.publish(event.id);
    console.log(`Live → https://tickitz.io/e/${event.id}`);
  4. 4
    Confirm a booking — ticket is auto-issued
    confirm.ts
    const booking = await tickitz.bookings.confirm("bkg_abc123");
    console.log(booking.ticket.qrUrl);    // hosted QR image URL
    console.log(booking.status);           // "confirmed"
Prices are in cents

4999 = $49.99 USD. All monetary values use the smallest currency unit to avoid floating-point issues.

Authentication #

Every request must include a valid API key passed as a Bearer token in the Authorization header.

shell
curl https://api.tickitz.io/v1/events \
  -H "Authorization: Bearer tk_live_••••••••••••" \
  -H "Content-Type: application/json"
Never expose your API key client-side

Keys carry full account access. Use them server-side only, stored in environment variables. Rotate immediately if compromised.

Key Rotation

Tickitz supports multiple simultaneous active keys so you can rotate without downtime.

  1. 1
    Create a new key in Dashboard → Settings → API Keys.
  2. 2
    Deploy the new key before revoking the old one.
  3. 3
    Revoke the old key once traffic has fully migrated.

Scopes & Permissions

Scope API keys to limit what they can access — useful for read-only integrations or third-party services.

ScopeDescription
events:readList and retrieve events
events:writeCreate, edit, publish events
bookings:readRead booking records
bookings:writeConfirm, cancel, refund bookings
checkin:writeScan QR codes and check in attendees
webhooks:writeRegister and manage webhook endpoints

Events API #

Events are the top-level object. Each event holds one or more ticket tiers, a capacity limit, and scheduling metadata. Events start as draft and must be published before they accept bookings.

POST/v1/eventsCreate an event
Creates a new event in draft state.
GET/v1/events/:idGet an event
GET/v1/eventsList events
POST/v1/events/:id/publishPublish an event
DELETE/v1/events/:idCancel an event
events.ts
const event = await tickitz.events.create({
  title:       "Neon Nights",
  description:"An immersive outdoor music experience.",
  startsAt:    "2025-08-10T20:00:00Z",
  endsAt:      "2025-08-11T04:00:00Z",
  venue: {
    name:    "Riverside Amphitheatre",
    address: "123 River Rd, Austin TX",
  },
  tiers: [
    { name: "Early Bird", price: 2999, quantity: 200 },
    { name: "General",    price: 4999, quantity: 800 },
    { name: "VIP",         price: 12999, quantity: 100},
  ],
  maxCapacity: 1100,
  settings: {
    requiresApproval: false,
    resaleEnabled:    true,
    refundPolicy:     "72h",
    queueEnabled:     true,
  },
});

Bookings API #

A booking represents a customer's intent to purchase tickets. Bookings move through a defined lifecycle:

StatusMeaning
pendingPayment intent created, awaiting confirmation
confirmedPayment captured, ticket auto-issued
cancelledBooking voided, ticket invalidated
bookings.ts
// Confirm a booking (call this from your payment webhook)
const booking = await tickitz.bookings.confirm("bkg_abc123");

console.log(booking.status);           // "confirmed"
console.log(booking.ticket.id);         // "tkt_xyz789"
console.log(booking.ticket.qrUrl);      // hosted QR image
console.log(booking.ticket.qrPayload);  // signed JWT for scanning

Queue / Waiting Room #

For high-demand events, the Queue module holds customers in a fair, position-based waiting room so you never oversell. Enable it per event with settings.queueEnabled: true. The SDK manages the polling loop automatically.

Handled 50,000 concurrent users

The queue module is battle-tested for high-demand drops. See the features page for benchmarks.

booking.ts
// 1. Customer joins queue
const entry = await tickitz.queue.join({
  eventId:    "evt_abc123",
  customerId: "cus_xyz789",
  items: [{ tierId: "tier_ga", quantity: 2 }],
});

// 2. Poll until ready
const final = await tickitz.queue.poll(entry.token, {
  onUpdate: ({ position }) =>
    console.log(`Queue position: #${position}`),
});

// 3. Confirm booking & issue ticket
const booking = await tickitz.bookings.confirm(
  entry.bookingId
);
console.log(booking.status); // "confirmed"
Queue tokens expire after 10 minutes

Once a customer reaches the front, they have 10 minutes to confirm their booking. After that, their slot is released to the next person in line.

QR Check-in #

Scan, verify, and check in an attendee in a single atomic call. Duplicate scans are caught automatically — no double-entry possible.

scanner.ts
const result = await tickitz.checkin.scan({
  qrPayload: scannedString,
  eventId:   "evt_abc123",
  scannedBy: "staff_gate_1",
});

if (result.alreadyCheckedIn) {
  // Duplicate scan — show warning
  alert(`⚠ ${result.attendeeName} already in`);
} else if (result.success) {
  // Admit the attendee
  alert(`✓ Welcome, ${result.attendeeName}!`);
  // result.tierName → "VIP"
  // result.checkedInAt → "2025-07-15T19:32Z"
} else {
  alert(`✗ Invalid — ${result.reason}`);
}

Response fields

FieldTypeDescription
successbooleanWhether check-in was accepted
alreadyCheckedInbooleanTrue if ticket was already scanned
attendeeNamestringName on the booking
tierNamestringTicket tier (e.g. "VIP")
checkedInAtISO 8601Timestamp of this scan
firstCheckedInAtISO 8601 | nullOriginal scan time (duplicates only)
reasonstring | nullFailure reason if success = false

Fraud Detection #

Every booking is automatically scored on a 0–100 risk scale. High-risk bookings fire a fraud.alert webhook and are held for review before tickets are issued.

ScoreRisk levelAction
0 – 29lowAuto-confirmed
30 – 69mediumFlagged for review
70 – 100highHeld, fraud.alert fired
fraud.ts
const report = await tickitz.fraud.getReport("bkg_abc123");

console.log(report.riskScore);   // 82
console.log(report.riskLevel);   // "high"
console.log(report.signals);     // ["velocity_breach", "vpn_detected"]
console.log(report.recommended); // "block"

// Manually approve a flagged booking
await tickitz.fraud.approve("bkg_abc123", {
  reviewedBy: "admin_uid_001"
});

Webhooks #

Webhooks deliver real-time push notifications whenever something happens in your account. All payloads are HMAC-SHA256 signed so you can verify their authenticity before processing.

Available events

booking.confirmedPayment captured, ticket issued
booking.cancelledBooking voided by customer or admin
ticket.createdNew ticket with QR code issued
ticket.usedTicket scanned, attendee checked in
queue.readyCustomer reached front of queue
queue.expiredQueue token expired without confirmation
fraud.alertHigh-risk booking (score ≥ 70)
event.sold_outAll tickets for a tier or event sold

Verifying signatures

webhook-handler.ts
import { verifyWebhook } from "@tickitz/sdk";

const isValid = verifyWebhook({
  payload:   req.body,
  signature: req.headers["tickitz-signature"],
  secret:    process.env.TICKITZ_WEBHOOK_SECRET,
});

if (!isValid) return res.status(401).send("Unauthorized");

Rate Limiting #

Requests are rate-limited per API key with a 60-second rolling window. Response headers tell you your current state:

HeaderDescription
X-RateLimit-LimitMax requests per minute
X-RateLimit-RemainingRequests remaining this window
X-RateLimit-ResetUnix timestamp when window resets
Retry-AfterSeconds to wait (429 responses only)
PlanReq / minBurst
Free6080
Starter100150
Professional1,0001,500
EnterpriseCustomCustom

Error Handling #

Tickitz uses standard HTTP status codes. Error bodies always include a machine-readable code and a human-readable message.

error-response.json
{
  "error": {
    "code":      "booking_not_found",
    "message":   "No booking with ID bkg_abc123 exists.",
    "status":    404,
    "requestId": "req_01HXYZ..."
  }
}
StatusCodeMeaning
400validation_errorInvalid request body or params
401unauthorizedMissing or invalid API key
403forbiddenKey lacks the required scope
404not_foundResource doesn't exist
409conflictAlready confirmed / ticket already used
429rate_limitedToo many requests — see Retry-After
500internal_errorSomething went wrong on Tickitz's end

SDKs & Libraries #

Official SDKs are maintained by the Tickitz team and updated with every API release.

Node.js
npm install @tickitz/sdk
TypeScript
Bundled with Node SDK
Python
pip install tickitz
Go
go get tickitz/sdk-go
Ruby
gem install tickitz
REST
Any HTTP client

Node.js / TypeScript

client.ts
import { Tickitz, type Event, type Booking } from "@tickitz/sdk";

const tickitz = new Tickitz({ apiKey: process.env.TICKITZ_API_KEY! });

const event: Event     = await tickitz.events.create({ ... });
const list              = await tickitz.events.list({ limit: 10 });
const booking: Booking  = await tickitz.bookings.confirm("bkg_abc");
client.js
const { Tickitz } = require("@tickitz/sdk");

const tickitz = new Tickitz({ apiKey: process.env.TICKITZ_API_KEY });

tickitz.events.list()
  .then(list => console.log(list.data))
  .catch(err => console.error(err));

Python

client.py
import os
from tickitz import Tickitz

client = Tickitz(api_key=os.environ["TICKITZ_API_KEY"])

event = client.events.create(
    title="Summer Festival",
    starts_at="2025-07-15T18:00:00Z",
    tiers=[{"name": "GA", "price": 4999, "quantity": 500}],
    max_capacity=500,
)
client.events.publish(event.id)
print(f"Live → https://tickitz.io/e/{event.id}")