Open app

September 25, 2026

Funnels are gone and milestones are here: declare what progress means in a stage and get a rate for it, over a denominator a funnel step never had. Every profile list is now one table you can sort, filter and choose columns on. And cohort tables follow your own calendar, stopping short of rates for history they never saw.

Threshold lines are gone; declare a milestone instead

Admin

A scoring model could carry threshold lines — "users is at least 10" — and every evaluation wrote a crossing or a recession onto the profile's timeline. Milestones now do the same job properly: the same crossing, plus a rate over the profiles that could have crossed it, and a place in the moves feed. So the Threshold lines card is gone from the scoring editor; Bands stay, since a band is part of what a score means.

The two lines that shipped on Profile value — 10 users, 5 projects — are withdrawn with it. Both are one-line milestones: Lifecycle → Milestones → New milestone, watch the property, and set the line as the level to cross. Crossings already on a profile's timeline stay there.

A milestone's rate is measured against its own stage

Admin

A milestone's eligible count was every profile in the workspace, not every profile in the stage the milestone lives under — so an activation milestone in a workspace of 10,000 profiles divided by 10,000 rather than by the few hundred actually in activation, and every rate read far too low. Milestone rates are now measured against the stage's own population, and the correction applies to milestones you already have: the next evaluation re-reads them.

A profile that has left the stage keeps counting. "Eligible" is a record of having been in a position to reach the milestone, not a check of where the profile is today — otherwise every rate would drift to 100% as profiles moved on.

A rule that mentions another milestone or monitor now works

Admin

A milestone or monitor rule could refer to another signal — "reached the connected a data source milestone", "the failing webhooks monitor is open" — and the condition read as false for everyone, always, with no error to say so. Rules like these now resolve, and the preview beside the editor agrees with what the evaluation will do. If you wrote one and wondered why it never fired, it will start reporting on the next cycle.

Fixes to the Expansion stage

Admin

Three things could put profiles in the Expansion stage who did not belong there:

  • A ladder or threshold milestone declared on another stage counted as expansion. Only milestones on the Expansion stage do now.
  • A milestone still in Observing counted toward the stage's conversion. Observing means observing: it records what it would have caught and changes no number until you press Promote.
  • A workspace with Expansion turned off still accrued expansion readings. It no longer does.

Also fixed: a monitor's stage scope could be narrowed but never widened again — clearing it saved as unchanged and the old scope came back.

Milestone rates now count everyone who could have reached one

Admin

Every milestone was reporting 100%. The rate is meant to be "how many of the profiles that could have reached this did", and the evaluation was only ever recording the ones that had — so the denominator and the numerator were the same set. Profiles that are eligible and have not reached a milestone are now recorded too, and the rate says what it always said it said.

Nothing to do: the next evaluation fills the denominator in, and the medians and move counts beside it were already correct.

A profile's timeline names what happened again

Admin

Milestones, plan changes and monitor trips were showing up on the profile timeline as signal.reached, with no detail under them. They read as Reached a milestone, Expanded, Contracted, A monitor tripped and A monitor resolved again, each with the line that says what moved and which way. Older rows are unaffected.

Also fixed: the evaluation audit line, which reported "0 entered, 0 converted" on every run, now reports what the signal pass actually reached and receded; and the hint under the milestone proximity scoring factor, which had been blank.

Milestones: say what progress means in a stage

Admin

Every stage's Overview now carries a Milestones list. A milestone is one thing worth reaching inside that stage — invited a teammate, connected a data source, upgraded a plan, crossed twenty-five seats — declared once and detected from the property values Uptend already syncs.

Each one reports the number a funnel step never had: how many of the profiles that could have reached it did. You say who could have with an optional eligibility rule, and the rate is measured against that denominator rather than against everyone in the stage. Beside it: the median time to reach it, and a marker on the first window, where Uptend had not yet read every profile.

Three shapes, two behaviours. A rule that becomes true fires once and never un-fires — a fact, not a state. A step up an ordered list and a number crossing a line record every move up and every move back, which is what makes a downgrade visible to churn risk.

A new milestone starts in Observing: it evaluates on every cycle and records what it would have caught, and counts toward nothing until you press Promote. Read a week of its numbers before you decide the rule says what you meant.

Expansion types have become milestones on the Expansion stage — the same ladders and thresholds, now listed beside the milestones of every other stage instead of in Settings. Everything they recorded is intact. Read more in Milestones.

Funnels have been removed

Admin

The funnel is no longer part of Uptend. The per-stage funnel list, the funnel editor, the Board view, funnel cohorts and the enrollment list are all gone, along with the Momentum scoring model each funnel owned.

Most of what a funnel measured was already being measured somewhere better. A stage reports its own conversion rate, its own cohorts and its own list of everyone in it — over every profile in the stage, not just the ones a funnel had enrolled. Getting stuck is what a monitor detects, with dwell and resolution the funnel never had. What a funnel really added was a declared list of the things you wanted profiles to reach, and that is coming back as a milestone: a thing a profile reaches, detected against the profile itself, with no enrollment to manage.

That milestone has landed — see below.

Fewer scores, all of them about a profile

Admin

There are four scoring models now — ICP fit, Profile value, Churn risk and Expansion readiness — and every one of them scores a profile. The Momentum model went with the funnel, and with it the Step progress and Velocity factors, which read an enrollment's position rather than anything about the profile. Every model is listed under Settings → Scoring.

One engine behind milestones and monitors

Admin

A milestone and a monitor turn out to be the same machinery asked of opposite questions, so they now share it: dwell before firing, one open episode per profile so nothing re-fires while it still holds, a re-baseline when you change what a rule means, and Observing mode. Milestones gain all four; monitors gain an eligibility rule, and with it a reportable rate for the first time.

You still see two things, because they are two things. A milestone is progress, lives under a stage, and you want the list full. A monitor is a problem, lives under Monitors, and you want it empty.

The evaluation cycle is three passes now — lifecycle states, then signals, then scores — where it used to be five. Nothing you configured has changed; the Data as of line names the signal pass where it used to name three.

Every property can be a column

Admin

The profiles list used to show three property columns, and it picked which three for you. A workspace with forty declared properties saw the same three forever, and the only way to ask about the other thirty-seven was to open profiles one at a time.

There is no cap now. Every property you have declared is a column you can add, alongside your scores and your lifecycle state. Use the Columns button to search the list, switch columns on and off by group, or reset to the default set.

A few columns are on by default rather than all of them — a table with forty columns is not a table anyone reads. For a usage metric, that default is its total; its weekly and rolling members are one click away.

Sort by any column

Admin

Click any column header to sort by it, and click again to reverse it. Numbers and dates start with the largest or newest first; text starts at A.

Rows with no value for the column you sorted by always sort last, in either direction. That is deliberate: "who is missing this" is a different question from "who has the least of it", and when you sort by a sparse property you are usually asking the first one.

Filter by any property

Admin

The profile lists now use the same filter bar as the Events and API log pages: only the filters you have applied are visible, and the rest sit behind Add filter. Each filter matches the kind of property it is on — pick several values from a list, set an upper and lower bound on a number or a date, match part of a piece of text, or choose yes or no.

Everything is in the URL, so a filtered, sorted, column-configured view is a link you can send to someone and they will see exactly what you saw.

The same table everywhere

Admin

All of the above applies to every profile list, not just the main one:

  • Profiles — everyone in the workspace.
  • A stage's Profiles view — everyone in that stage right now. Reactivation no longer has its own different table; the columns it used to exist for are columns you can add to any stage.

The Monitors index picks up the same filter bar and sortable columns.

Your view is remembered

Admin

The columns and the sort you choose are remembered per view, so coming back to a page — after a refresh, or after navigating away — shows the view you set up rather than resetting to the default. A stage's table and the main profiles table remember separately, since they are answering different questions.

A link always wins over what was remembered, so a URL someone sends you shows their view, not yours.

Cohorts follow your calendar

Admin

Cohort buckets used to be rolling slabs: a "week" was the last seven days counted back from whenever you loaded the page, and a "month" was thirty days. Neither lined up with a calendar, so the rows never matched the weekly and monthly numbers you already report.

They are real calendar weeks and months now. A month row is simply called September 2026; a week row is the week it actually is. The row you are currently inside is marked In progress, so a period that is still filling up is not mistaken for a finished one.

Two new settings decide where those boundaries fall, under Settings → General → Calendar:

  • Timezone — the zone your days start and end in. A signup at 11:30pm on 31 March belongs to March in New York and to April in UTC.
  • Week starts on — Monday, Sunday, or whichever day your reporting uses.

Both save themselves as soon as you pick them, and both are also available on GET and PATCH /v1/workspaces/{id}.

A cohort table no longer guesses

Admin

Connecting a data source imports everyone at their real signup date, but it cannot tell us when each of them did anything — those timings are filled in from how things look today. Cohort tables were averaging those filled-in timings, which is why a newly connected source produced the same suspiciously high rate for every week in the past. The table even labelled the rows "History starts here" — and then printed the number anyway.

Now it doesn't. A cell we cannot calculate honestly shows –, and the row says Not collecting yet. You still see how many profiles are in the cohort, because that part is real; only the rates are withheld.

What is never withheld is where a cohort stands today — that is a count of profiles as they are now, not a claim about when something happened. It is the last filled cell in each row, a different column for an older cohort than for a younger one, and it reports even when the rest of the row is withheld.

A blank cell means something different from a dash, and now looks it: the cohort is not old enough to have reached that point yet, so the cell is left genuinely empty rather than dashed.

A brand-new workspace will now show mostly dashes where it used to show confident numbers. That is the correction: the numbers were not real, and they fill in as the data arrives.

Charts shade on one ramp, in both themes

Admin

Cohort cells used to shade green above 75% and grey above 40% — three hard steps that read like a pass/fail badge, and a green that was nearly invisible in dark mode. Every rate now shades on a single five-step ramp built from Uptend's own blue, so a table reads as one quantity getting larger and is legible in both themes.

The webhook delivery and response-time charts also had fixed light-mode colours baked in; those follow the theme now too.

On this page