links.arjun.tv/docs/end-user/best-practices/events-ticketing

Events and Ticketing

Best practices for event organizers, ticketing platforms, and conference operators using 10x to manage dynamic pricing, inventory-aware routing, early-bird workflows, and real-time event triggers.

Business problems

  1. Manual pricing tier transitions — When early-bird pricing ends, someone has to manually update links or landing pages.
  2. Sold-out links go nowhere — When tickets sell out, the promotional link returns a 404 instead of routing to a waitlist.
  3. No real-time event triggers — Business events (early-bird deadline, sellout, speaker announcement) cannot dynamically change where links route visitors.
  4. Multi-tier ticket routing — VIP, general admission, and student tickets need different landing pages but share the same promotional URL.
  5. Post-event attribution gaps — It is unclear which channels and campaigns actually drove ticket sales.

Feature-to-problem map

Problem10x featureGuide
Manual pricing transitionsLink scheduling (scheduledStartAt, scheduledEndAt)Advanced Link Controls
Sold-out dead linksRouting rules with priority-based fallbacksAdvanced Link Controls
No real-time triggersChain signals with event-driven rulesChain Signals and Prefetch
Multi-tier routingSegment and source-based routing rulesSmart Link Personalization
Attribution gapsCampaign funnel tracking with ctx tokensCampaign Funnel Workflow

Recommended workflows

1. Automate early-bird to regular pricing with scheduling

Create two links: one for early-bird and one for regular pricing. Use scheduling to control when each is active:

Early-bird link (active until March 15):

PUT /v2/handles/{handle}/links/conf-earlybird
{
  "destinationUrl": "https://events.example.com/conf-2026?tier=earlybird",
  "title": "Conference 2026 - Early Bird",
  "scheduledEndAt": "2026-03-15T23:59:59Z"
}

Regular pricing link (active from March 16):

PUT /v2/handles/{handle}/links/conf-regular
{
  "destinationUrl": "https://events.example.com/conf-2026?tier=regular",
  "title": "Conference 2026 - Regular",
  "scheduledStartAt": "2026-03-16T00:00:00Z"
}

When the early-bird link expires, visitors see HTTP 410 (Gone). Share the regular link in parallel — it activates automatically on March 16 without manual intervention.

For a single-URL approach, use a chain signal instead (see workflow 3 below).

2. Route sold-out traffic to a waitlist

Set up routing rules so your primary link has a fallback destination:

PUT /v2/handles/{handle}/links/conf-tickets
{
  "destinationUrl": "https://events.example.com/conf-2026/tickets",
  "routingRules": [
    {
      "priority": 10,
      "destinationUrl": "https://events.example.com/conf-2026/vip",
      "conditions": { "segmentIn": ["vip_interest"] }
    },
    {
      "priority": 20,
      "destinationUrl": "https://events.example.com/conf-2026/student",
      "conditions": { "sourceIn": ["edu", "student-portal"] }
    }
  ]
}

When general admission sells out, update the base destination to the waitlist:

PUT /v2/handles/{handle}/links/conf-tickets
{
  "destinationUrl": "https://events.example.com/conf-2026/waitlist"
}

The routing rules remain intact — VIP and student traffic still goes to their respective pages, while all other traffic now hits the waitlist. No need to change the shared short URL.

3. Trigger dynamic routing with chain signals

Use chain signals for real-time business events that should change routing behavior. When early-bird pricing expires, your backend posts a signal:

POST /v2/public/chain/signals
{
  "handle": "conference",
  "sessionId": "sig_conference_1740500000000_abc123",
  "eventType": "early_bird_deadline",
  "signals": [
    { "signalKey": "early_bird_status", "signalValue": "expired", "confidence": 1.0 }
  ]
}

A chain rule routes visitors accordingly:

{
  "ruleId": "earlybird-expired",
  "enabled": true,
  "priority": 100,
  "triggerEvent": "page_view",
  "chainConditions": {
    "require": [
      { "signalKey": "early_bird_status", "operator": "equals", "signalValue": "expired" }
    ]
  },
  "action": {
    "type": "redirect",
    "destinationUrl": "https://events.example.com/conf-2026?tier=regular"
  }
}

When tickets sell out completely:

{
  "ruleId": "sold-out",
  "enabled": true,
  "priority": 50,
  "triggerEvent": "page_view",
  "chainConditions": {
    "require": [
      { "signalKey": "ticket_status", "operator": "equals", "signalValue": "sold_out" }
    ]
  },
  "action": {
    "type": "redirect",
    "destinationUrl": "https://events.example.com/conf-2026/waitlist"
  }
}

The sold-out rule has priority 50 (higher than early-bird at 100), so it takes precedence when both signals exist.

4. Track ticket sales by channel with campaigns

Create campaigns for each promotional channel:

POST /v2/handles/{handle}/campaigns
{ "campaignId": "conf-email", "goalType": "PRODUCT_SALE", "status": "ACTIVE", "primarySlug": "conf-tickets" }
{ "campaignId": "conf-social", "goalType": "PRODUCT_SALE", "status": "ACTIVE", "primarySlug": "conf-tickets" }
{ "campaignId": "conf-partner", "goalType": "PRODUCT_SALE", "status": "ACTIVE", "primarySlug": "conf-tickets" }

On your checkout success page, fire the conversion with the ctx token:

POST /v2/public/conversions
{
  "ctx": "<token from redirect>",
  "eventType": "purchase",
  "value": 299.00,
  "currency": "USD",
  "idempotencyKey": "ticket-order-12345"
}

Compare channel performance:

GET /v2/handles/{handle}/analytics?funnel=true

This returns clicks, conversions, and revenue for all campaigns. Identify which channel delivers the best cost-per-acquisition.

5. Use click caps for limited-quantity offers

For flash sales or limited VIP allocations, set a click cap on the link:

PUT /v2/handles/{handle}/links/vip-flash
{
  "destinationUrl": "https://events.example.com/conf-2026/vip-flash",
  "maxClicks": 100,
  "expiresAt": "2026-03-01T18:00:00Z"
}

After 100 clicks or the expiry time (whichever comes first), the link returns HTTP 410 (Gone). Combine with a scheduled backup link that activates after the flash sale ends.

6. Prefetch decisions for client-side personalization

If your event page needs to make multiple routing decisions (show countdown, show waitlist banner, show tier pricing), use prefetch:

POST /v2/public/chain/prefetch
{
  "handle": "conference",
  "sessionId": "sig_conference_1740500000000_abc123",
  "triggerEvents": ["page_view", "scroll_50", "exit_intent"]
}

The response includes a decision for each trigger event, cached for 60 seconds. Your client renders the right content without multiple API round-trips.

Key metrics to track

MetricWhere to find itWhat it tells you
Ticket sales per channelFunnel analytics by campaignIdWhich promotions drive sales
Conversion rate by tierSegment analytics with ticket tier segmentsVIP vs. general admission efficiency
Revenue by geographyGET /v2/handles/{handle}/analytics?groupBy=countryWhere attendees are coming from
Sell-through velocityConversion timestamps in exportHow fast tickets sell
Waitlist capturesConversion events with eventType: waitlist_signupDemand beyond capacity

Common mistakes

  1. Not setting up fallback routing before tickets sell out. Update the link destination proactively. Once sold out, visitors hitting a dead page are lost.
  2. Using scheduling alone for pricing transitions. Scheduling is clock-based. For inventory-driven transitions (sellout), use chain signals that react to real events.
  3. Forgetting to space rule priorities. Put critical rules (sold-out) at lower priority numbers (higher precedence) than tier-specific rules. If sold-out is priority 200 and VIP routing is priority 10, VIP visitors still route to VIP even when sold out.
  4. Not testing with route preview. Before going live, verify routing decisions:
   POST /v2/handles/{handle}/links/conf-tickets/route-preview
   { "country": "US", "device": "MOBILE", "source": "email" }
  1. Setting click caps without a backup link. When maxClicks is reached, the link returns 410. Have a follow-up link or waitlist ready for overflow traffic.

Related: