io.tt SDK Docs
GuidesExperiences

Golden Ticket

Implementing Instant-Win / Odds-Based Promotions with the io.tt SDK

The Golden Ticket template supports instant-win and odds-driven prize mechanics. Unlike Raffle, Golden Ticket resolves winning, losing, and code validity immediately through the server-side odds engine.

This guide covers the four Golden Ticket methods:

  • getGoldenTicketStatus
  • checkGoldenTicketEntry
  • claimGoldenTicketCode
  • signupForGoldenTicket

These methods let you build a full end-to-end Golden Ticket experience where a user enters a code, the server instantly determines the outcome (win/lose/already claimed), and winners can submit their details.


Overview of the Golden Ticket Flow

A typical instant-win Golden Ticket flow works like this:

  1. User scans a product → you receive a goldenTicketId
  2. Check whether the experience is active → getGoldenTicketStatus
  3. Optionally check whether this user has already entered → checkGoldenTicketEntry
  4. Resolve the golden ticket code against the odds engine → claimGoldenTicketCode
  5. If winner → collect details → signupForGoldenTicket
  6. Show final confirmation

1. Initialise the SDK

Create a single SDK instance using your Experience API key. If you haven't set this up yet, see Getting Started.

import { IOTT } from "@io-tt/sdk";

const sdk = new IOTT({
  apiKey: process.env.IOTT_API_KEY,
});

2. Check Golden Ticket Status

Before showing any UI, confirm the promotion is currently active. This allows you to route the user to an appropriate closed or not-yet-started screen rather than presenting a code entry form against an inactive experience.

const status = await sdk.getGoldenTicketStatus(EXPERIENCE_ID);

if (!status.isActive) {
  renderPromotionEndedScreen();
  return;
}

The returned GoldenTicketStatus object includes:

FieldTypeDescription
isActivebooleanWhether the experience is currently active
hasEndedbooleanWhether the experience has ended
startDateDate | nullScheduled start date
endDateDate | nullScheduled end date

3. Check If the User Has Already Entered (Optional)

Before showing the code entry form, you can check whether this user has already entered the promotion. This prevents showing a form the server will reject and lets you display a more appropriate "already entered" state instead. This step requires you to have collected the user's identifier (typically their email) first.

const entry = await sdk.checkGoldenTicketEntry(EXPERIENCE_ID, uid);

if (entry.hasEntered) {
  renderAlreadyEnteredScreen();
  return;
}

4. Claim a Golden Ticket Code

(Instant-win resolution happens here)

This is where the outcome is determined. The server validates the code against the configured odds engine and immediately returns whether the user has won, lost, or whether the code has already been claimed. No further server calls are needed to determine the result.

const result = await sdk.claimGoldenTicketCode(
  EXPERIENCE_ID,
  uid,
  goldenTicketCode
);

The server determines:

  • Whether the code is valid
  • Whether it has already been claimed
  • Whether it is a winner according to configured odds

Branching Logic

Not a Winner

if (!result.isWinner) {
  renderNotAWinnerScreen();
  return;
}

Winner

const prize: GoldenTicketPrize | undefined = result.prize;
renderWinnerScreen(prize);

GoldenTicketPrize has the shape { sku: string; quantity: number }.


5. Submit Winner Details

Once a winner is confirmed, collect their details for prize fulfilment. Only uid and code are required — all other fields are optional and should only be collected if your experience form asks for them. Winner details are automatically routed to your configured CRM.

await sdk.signupForGoldenTicket(
  EXPERIENCE_ID,
  {
    uid,                     // required
    code: goldenTicketCode,  // required
    email,                   // If using email as the uid, pass the same value here too
    // Personal details (all optional)
    title,
    firstName,
    lastName,
    gender,                  // 'male' | 'female' | 'other'
    phoneNumber: { countryCode: 44, number: '7700900000' },
    dateOfBirth,             // ISO 8601 string, e.g. "1990-01-15"
    // Address (all optional)
    addressLine1,
    addressLine2,
    locality,
    administrativeDivision,
    postalCode,
    country,
    // Consent (all optional)
    marketingConsent,
    profilingConsent,
    // Custom fields (optional)
    extra: {
      // additional custom fields
    },
  },
  images,                    // optional: Array<File | Blob | Buffer>
);

Only uid and code are required. All other entry fields and the images argument are optional.

When using email as the uid (the most common pattern), pass the same value to both uid and email. See the CRM Integration Guide for how these fields are routed to your configured CRM.


6. Summary Table

MethodSignaturePurpose
getGoldenTicketStatus(experienceId)Check whether the experience is currently active and retrieve start/end dates.
checkGoldenTicketEntry(experienceId, uid)Determine whether this user has already entered the promotion.
claimGoldenTicketCode(experienceId, uid, code)Submit a code to the odds engine — instantly resolves win, loss, or already-claimed.
signupForGoldenTicket(experienceId, entry, images?)Submit winner contact details, consent, and optional images for prize fulfilment.

On this page