TicketSignal

How TicketSignal works

TicketSignal forecasts the final attendance of a live show from the tickets sold so far and the hours until the start. It finds past shows that stood in the same position at the same point in their sales and reports how they finished.

By Duncan Wold. Updated October 30, 2026.

3,690past shows in the reference data
114,719paid ticket sales, each with a timestamp
8 yearsDecember 2014 to February 2023
9,656forecasts back-tested, walk-forward

The problem

Ticket sales for live events are back-loaded: most tickets sell late. A straight line through sales so far misleads, and a single average of past shows ignores both the room and the timing. Forty tickets sold means something different ten days out than two days out.

The question TicketSignal answers: of all past shows that had about 40 tickets sold about 48 hours before the start, how did they finish?

Where it came from

The method was built in 2018 at PianoFight, an independent San Francisco theater co-founded by the author, as a tool for its operations team. It was released as open source under the MIT license. PianoFight closed in March 2023.

TicketSignal reimplements the method as a Python API with a database and authentication. Porting it exposed five defects in the original JavaScript, such as a mistyped loop variable in the free-ticket filter and an operator-precedence error in the room filter. Each is fixed and documented in the source.

The data

RoomCapacity usedShowsPaid salesAvg. final
main1201,80978,85143.6
second601,88135,86819.1

Included: completed, publicly listed shows that were not free RSVP events, counting paid tickets that were not cancelled or refunded.

Privacy: customer names and emails are dropped at import. Only each sale's timestamp and price are stored. The raw exports are not published and have never been committed to the code repository.

The method

  1. State. Room, tickets sold and hours until the start, with a tolerance box around them (default 2 tickets, 4 hours).
  2. Votes. Each past show in the same room whose sales passed through the box contributes its final attendance.
  3. Probabilities. Bayes' rule turns the counts into a probability for every possible final number. The prior is estimated from the data (empirical Bayes).
  4. Smoothing. A weighted window (default 10 tickets) removes spikes caused by single shows.
  5. Output. The point forecast is the distribution's mean. The interval expands symmetrically around it until it holds the requested probability (default 80%). Results never exceed room capacity.
P(final = n | state)  =  P(state | final = n) x P(final = n) / P(state)

state = (tickets sold  +/- tolerance,  hours before start  +/- tolerance)

With too few matching shows, the service returns a warning or an error instead of a number.

A worked example

Main room, 40 tickets sold, 48 hours to go: 99 of the 1,809 main-room shows passed through that state.

Admit: most likely house
69 tickets
99 past shows matched · 1,809 in corpus
46 to 92
80% credible

Second room, 20 sold, 72 hours out: 36 tickets, 80% range 23 to 49, from 102 matching shows. Both computed on this data on October 30, 2026.

curl -G https://api.ticketsignal.io/v1/forecast \
  -d stage=main \
  -d tickets_sold=40 \
  -d hours_until_start=48

Does it work? A back-test

Method. Walk-forward: each show is forecast using only shows that started before it. Forecasts at 7 days, 3 days, 2 days, 1 day and 6 hours before the start, with the live service's default settings and no tuning. A forecast is scored when the show had at least 5 tickets sold at that point. Result: 9,656 forecasts for 2,342 shows, February 2016 to February 2023. Baselines: room average, tickets sold so far, and tickets sold so far scaled by the historical ratio of final to sold-so-far at the same point (the ratio rule).

OutForecastsError: TicketSignalError: best simple rule80% range heldBias
7 days1,38812.822.981%-2.3
3 days1,80610.318.684%-0.7
2 days1,9729.115.785%0.0
1 day2,1527.611.789%+0.4
6 hours2,3385.97.794%+0.6
All9,6568.714.787%-0.2

"Out" is the time before the start. Error is the mean absolute difference in tickets between forecast and actual final attendance. Bias is the mean of forecast minus actual; negative means too low. "Best simple rule" is the best of the three baselines at each time (the ratio rule in the "All" row).

Scope. Retrospective, one venue, shows that took place only. Scored forecasts cover 61% of main-room shows at 7 days and 84% at 6 hours (second room: 30% and 67%), because only shows with at least 5 tickets sold are scored. Baselines are simple rules, not machine-learning models. The scripts are in the project repository.

Using the API

EndpointPurpose
GET /v1/forecastFinal-attendance forecast. Parameters: stage, tickets_sold, hours_until_start; optional tix_delta, time_delta_hours, smooth_by, confidence.
GET /healthLiveness check with corpus size.
POST /v1/beta-signupsJoin the beta list.

The forecast response contains point_forecast, ci_low, ci_high, events_in_state, probabilities (every possible final number) and warnings. Anonymous use is rate limited per address; API keys, issued by hand, raise the limit. Reference: api.ticketsignal.io/docs. Specification (OpenAPI 3): api.ticketsignal.io/openapi.json.

How it is built

Limits

Links

Try the live demo API docs OpenAPI spec Original open-source tool