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
- Manual pricing tier transitions — When early-bird pricing ends, someone has to manually update links or landing pages.
- Sold-out links go nowhere — When tickets sell out, the promotional link returns a 404 instead of routing to a waitlist.
- No real-time event triggers — Business events (early-bird deadline, sellout, speaker announcement) cannot dynamically change where links route visitors.
- Multi-tier ticket routing — VIP, general admission, and student tickets need different landing pages but share the same promotional URL.
- Post-event attribution gaps — It is unclear which channels and campaigns actually drove ticket sales.
Feature-to-problem map
| Problem | 10x feature | Guide |
|---|---|---|
| Manual pricing transitions | Link scheduling (scheduledStartAt, scheduledEndAt) | Advanced Link Controls |
| Sold-out dead links | Routing rules with priority-based fallbacks | Advanced Link Controls |
| No real-time triggers | Chain signals with event-driven rules | Chain Signals and Prefetch |
| Multi-tier routing | Segment and source-based routing rules | Smart Link Personalization |
| Attribution gaps | Campaign funnel tracking with ctx tokens | Campaign 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
| Metric | Where to find it | What it tells you |
|---|---|---|
| Ticket sales per channel | Funnel analytics by campaignId | Which promotions drive sales |
| Conversion rate by tier | Segment analytics with ticket tier segments | VIP vs. general admission efficiency |
| Revenue by geography | GET /v2/handles/{handle}/analytics?groupBy=country | Where attendees are coming from |
| Sell-through velocity | Conversion timestamps in export | How fast tickets sell |
| Waitlist captures | Conversion events with eventType: waitlist_signup | Demand beyond capacity |
Common mistakes
- Not setting up fallback routing before tickets sell out. Update the link destination proactively. Once sold out, visitors hitting a dead page are lost.
- Using scheduling alone for pricing transitions. Scheduling is clock-based. For inventory-driven transitions (sellout), use chain signals that react to real events.
- 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.
- 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" }
- Setting click caps without a backup link. When
maxClicksis reached, the link returns 410. Have a follow-up link or waitlist ready for overflow traffic.
Related: