---
title: Changelog
description: What changed in Laver, newest first, with API behaviour changes called out.
section: Troubleshooting
order: 2
---

# Changelog

Customer-visible changes, most recent first. Anything that changes how the API
behaves is labelled **API change** — those are the entries to read if you have
an integration or an agent running against Laver.

Internal refactors, test and tooling work are not listed.

## 1 August 2026

### A workspace now needs a live subscription

**API change — breaking.** A workspace with no live subscription is locked, and
the lock covers **reads as well as writes**. Boards, tickets and the wiki answer:

```json
{
    "error": "This workspace does not have an active subscription. Start one in Billing to get back in.",
    "subscription_required": true
}
```

with HTTP `402`. Billing, sign-in and profile routes keep working, so an owner
can always reach the page that restarts the subscription.

New workspaces start a 14-day trial taken with a card up front, on the paid
plan's limits. If you have an integration that previously read a board on a
workspace with no subscription, it now needs to handle `402`. See
[Errors](/docs/troubleshooting/errors).

### Seats, plan limits and non-payment states

**API change.** Billing is now enforced end to end:

- The free plan allows 3 seats, 2 boards and 1 GB of storage. The paid plan is
  unlimited. Exceeding a limit answers `402` with a body that quotes the current
  price in a `prices` object.
- Viewers are free and never count as a billable seat. Outstanding invitations
  do count, so ten pending invites can no longer walk a workspace past its cap.
- A workspace behind on payment stays fully readable but stops growing: new
  members, boards and uploads are refused with `402`.
- A workspace further behind becomes read-only. Writes answer `402` with
  `billing_frozen: true`; every read keeps working.
- Support-comped workspaces are supported without a Stripe subscription.
- Tax is calculated at checkout where it applies.

### Wiki pages can be reordered

Pages can be dragged into a new order within their parent, and the order sticks
for everyone.

## 31 July 2026

### Billing and subscriptions

- **One paid plan.** The plan choice was collapsed to a single Pro plan, monthly
  or annual.
- **Pricing and renewal are visible.** The billing screen shows what you pay,
  in your currency, and when it renews. **API change:** plan-limit refusals now
  carry a `prices` object so a client can offer the upgrade in place.
- **Deleting a workspace cancels its subscription.** Previously the workspace
  went away and the subscription did not.
- **Payment updates are applied in order, and only once.** Out-of-order or
  repeated notifications from the payment provider no longer flip a workspace's
  billing state back and forth.

### Working with tickets over the API

- **Read one ticket without reading its board.** `GET /tasks/<uuid>` returns a
  single ticket including its `version`, so a write no longer needs a whole
  board fetch first.
- **A `409` now tells you the current version.** **API change.** A version
  conflict answers
  `{"error": "Task was updated by another request.", "version": 9}` — you can
  retry without re-reading. Previously you had to go and find the version out
  for yourself.
- **Search a board, and address a column by name.** `GET /boards/<uuid>/tasks`
  matches a substring of the title or description with `q`, and filters by
  column with `status` (a name) or `status_uuid`. Column names are accepted
  anywhere a `status_uuid` is, on creating and moving tickets too, so an agent
  can say "In Progress" rather than hold a uuid.
- **Ask a board what changed since last time.** **API change.** Every board read
  returns `server_time`; pass it back as `updated_since` and the reply carries
  only what changed, plus `removed_task_uuids` for what left the board.
- **Deltas report cross-board moves.** **API change.** A ticket moved to another
  board now appears in the source board's `removed_task_uuids` instead of
  lingering in a client's copy.
- **Deltas carry board metadata.** **API change.** A delta response now includes
  the board, its columns, swimlanes, members, labels and card preferences, so a
  client can apply one without a second request.
- **Board search can be walked a page at a time.** `limit` (1–200, default 50)
  and a `cursor`/`next_cursor` pair. The cursor is a keyset, so tickets changing
  mid-walk cannot make it skip or repeat a row.
- **Body-less `POST`s no longer need a body.** **API change.** Calls such as
  archive stopped requiring a pointless `{}`; previously they answered
  `400 body must be object`.

### API keys

- **Agent-friendly API keys.** Workspace owners and admins can issue `laver_`
  bearer tokens from **Admin → API keys**. A key acts as the person who created
  it and inherits exactly their access, so there is no second permission model:
  change their role and the key changes with it, deactivate them and the key
  stops.
- **Members can issue their own key.** `POST /profile/api-keys`, up to ten live
  keys per person per workspace. A key cannot mint further keys.
- **Changing your password no longer kills your API keys.** They were being
  revoked along with sessions, which they are not.

### Live board updates

- **Server-sent events per board.** `GET /boards/<uuid>/events` pushes a frame
  whenever anything on the board changes, so open boards update without waiting
  for the next poll. The frame says only that something changed — fetch a delta
  to find out what.
- **The board refreshes from a delta** rather than re-reading everything, which
  makes a busy board noticeably lighter on both ends.
- **The rate limiter no longer takes a board down.** The allowance was raised to
  900 requests per minute and event streams were exempted; previously a `429`
  triggered a reconnect loop that `429`d again.
- **The event stream works cross-origin.** It was being blocked by the browser
  despite answering `200`.

### Boards and tickets in the app

- **Success criteria on a ticket.** A checklist on each ticket, with a progress
  badge on the card. (Named _subtasks_ when it shipped; the API path is still
  `/tasks/<uuid>/subtasks`.)
- **Split view.** Open a second board beside the first.
- **Boards behave as tabs**, preloaded, so switching between them is instant.
- **Multi-select and group actions.** Select several tickets and move, label or
  archive them together.
- **Columns can be re-arranged**, and each column carries its own hover shortcut
  on a card, so a ticket can be moved without opening it.
- **Ticket dialog fixes.** Tickets no longer close the instant they are opened,
  no longer reload themselves on every board poll, and no longer refetch in a
  loop while open. Boards no longer lock up after a ticket is moved.
- **Ticket layout.** Action buttons moved to the eyebrow row, the title got the
  full width, the actions menu got a control that is not the right-click menu,
  and card cover images now bleed to the card edges.
- **Attachment previews** got a viewport-sized stage and several fixes.
- **Sidebar and filters.** Boards show their initial in the sidebar chip, the
  board filter opens ready to type, the collapsed workspace tile was rebuilt, the
  app version is shown, and there are no more warning toasts when there was
  simply nothing to load.

### Working offline and on a phone

- **Laver survives a bad connection.** Changes made while offline are queued and
  replayed when the connection returns.
- **The offline queue no longer replays one person's writes as another.**
  Queued changes are now bound to the account that made them and are discarded
  on sign-out.
- **Mobile.** Long-press drag and drop with the drag scoped to the pointer that
  started it, column-snapping board scrolling, safe-area handling, notifications
  in the board navigation, one consistent breakpoint across the app, no
  autofocus on the ticket title, and the ticket dialog grab pill removed.

### Wiki

- **The editor is faster**, and images and tables can be resized — with the
  resize handles actually reachable.
- **Drafts no longer destroy or strand work.** The draft layer could lose an
  edit or leave it unreachable; it does neither now.
- **`@`-mentions render inside the open dialog** instead of behind it.

### Security and accounts

- **Password resets are all-or-nothing.** A reset that failed part-way used to
  report success while leaving the account in between states. It now rolls back
  completely.
- **Hardening.** Security headers, HTML escaping in email, upload and attachment
  checks — including verifying that a file's contents match the type it claims —
  session handling, content-security policy, and validation of rich-text content
  on the way in.
- **Two-factor sign-in is not currently available.** Its endpoints are closed
  while the feature is disabled, rather than half-open.
