Three separate things, often confused:
- Platform role: staff or member. It governs the admin console. It never
decides feature access. - Organization role: admin or member of one organization: who can invite,
manage billing, mint keys. - Entitlements: what you can actually do, and these come from plans.
Plans are rows, not code
A plan carries features (capabilities like data downloads or API access) and
limits (numeric allowances) as data. A new tier: a university site licence, a
lab plan: is a new row created in the admin console, not a deploy.
The rows today
| Plan | Sold as | Seats | What it adds |
|---|---|---|---|
| Free | never; the fallback | 1 | the explorer, prices, tracking, the research workspace |
| Plus (monthly or annual) | one subscription | 1 | data downloads, the API and MCP, the assistant, 100 spaces |
| Team (annual) | per seat, at least 3 | the number bought | everything in Plus for every seat, higher limits |
| Institution (annual) | per seat, at least 25 | the number bought | Team plus publishing and the assistant, much higher limits |
Per-seat plans have a quantity. The buyer chooses how many seats at
checkout (no fewer than the plan’s minimum), the subscription carries that
number, and the organization’s allowance follows it: raise or lower the seat
count and the allowance moves with it. Buying team seats from a personal
account turns that account’s organization into a team, with the buyer as its
administrator; rename it from the organization page.
The per-seat price is set in the admin console, not in code. The two
per-seat rows ship without a price. Until staff enter one on /admin/plans,
the pricing page shows the plan as a conversation (“talk to us about seats”),
it cannot be checked out, and bin/rails stripe:setup reports it as skipped
rather than inventing a figure. Entering a price puts it on sale: the pricing
page shows the per-seat maths, the billing page offers it with a seat count,
and the next stripe:setup creates its Stripe price under its lookup key
(dfrds_team_annual_seat, dfrds_institution_annual_seat). The Plus keys,
dfrds_data_monthly and dfrds_data_annual, are live and never change.
Publishing on the institution row is recorded as a plan feature for the
tier’s definition; today publishing itself is a switch on each organization’s
page and is free, so the feature flag describes the tier rather than gating
anything yet.
Best plan wins
A user’s access is the best plan across all their organizations. A student
with a free personal organization who is also a member of a covered university
gets the university’s access. Lose the seat, lose the access; keep the personal
organization either way.
When a subscription lapses, the organization falls back to Free rather than
breaking.
Limits
Limits are enforced where they are used: projects, saved items, alerts, API
calls per hour, and a refusal says which limit was hit and what to do about it.
Spaces
| Plan | Spaces you can create |
|---|---|
| Free | 1 |
| Plus (monthly or annual) | 100 |
| Team | 100 |
| Institution | 500 |
Your personal space is outside the allowance. The space made for you when
you signed up is not one of the ones you create, so a free account can still
make one of its own — a shared desk for a paper, say — and keep its personal
space for everything else.
The allowance is shown on your Spaces page before you reach it, and the
“New space” button stays visible and disabled once it is spent, with the
reason. Leaving a space frees the slot.
If you are on a paid plan, 100 is a ceiling rather than a target: it exists so
that spaces cannot be used to sidestep per-space member limits.