Changelog

What's new in CallSee.me

RSS
improvement

The guided tour was filmed on a laptop, and it showed

Our guide videos are recorded by a robot. It opens a browser, creates a meeting, invites someone, ends the call, and we publish the film. It is a nice way to make documentation that cannot drift from the product, because the product is what

feature

We were selling a feature we did not have

The Enterprise plan listed "custom domains" among its features. It should not have. There was nothing behind that line: no way to claim a hostname, no way to prove you own one, nothing to route it anywhere. It read like a shipped feature

improvement

An hour is sixty minutes, and now the invoice agrees

Per-hour billing has been rebuilt on Stripe's current metering system. The old one still worked, but it was built on a mechanism Stripe has since retired, and "still works" is a poor foundation for the part of the product that decides what

improvement

The watchman who could not prove he had looked

Every hour, whether anybody is using CallSee.me or not, we place a real call against the live service. Three participants, actual cameras, actual audio, one of them deliberately forced down the slowest path available so we find out

fix

The release that wasn't

Yesterday's release notes described a fix for people with no microphone getting no camera either. Everything in them was true except the part that mattered: nothing had been delivered. The version was cut, the notes were published, and

improvement

A missing microphone should not cost you your camera

If you dropped our embeddable meeting component into your app and the person using it had no microphone — a desktop with no headset, a borrowed machine, a browser that had quietly denied audio months ago — the call came up with no

fix

Check your hair before others join

Our embeddable meeting component has shown you every person in the call except yourself, for its entire existence. Not a regression, not a recent break — it simply never rendered your own camera. Anyone who dropped the one-tag version

improvement

Your key is fine, it's the wrong shape

There are three reasons we might turn down an API key: we have never seen it, it is real but it is the wrong kind for the endpoint you called, or it is real and the right kind and simply lacks permission. Until today all three came back as

improvement

The monitor was the one hallucinating

Every hour, from two places on the internet, we place a real three-way video call into production and watch it the way a person would: did the picture arrive, is it still arriving a minute later. Seven times in the last four days it came back and

improvement

Provisioning a key can no longer take one away

Getting a service key for an organisation and *replacing* the one it already has used to be the same request. Ask for a test credential, and the key running that organisation's production traffic was quietly swapped underneath it — a fresh

improvement

Telling integrators the truth about versions

If you build on our SDK, the API can tell you which version is current. Today it points at the one that actually exists, which sounds like it should never have been in question and is exactly the sort of thing that drifts quietly.

improvement

The addresses now check themselves

Nothing in this one changes what you see. It changes how a piece of the calling system looks after itself.

improvement

The ghost was us

The last two releases chased participants who haunted a meeting after leaving. This one found out where most of the ghosts were actually coming from: us. Every browser joining a call was opening its signalling connection, throwing it away

improvement

Leaving properly

The other half of the ghost problem. Last release stopped a departed participant haunting your meeting for its full length; this one stops most of them appearing in the first place.

improvement

The people who were never there

If someone's connection dropped, the meeting could keep believing they were still in the room — and anyone joining shortly afterwards would quietly try to call them. That attempt never went anywhere and never gave up, so their name

improvement

A test you can run on us

If you build on our SDK, you can now check it yourself. One command puts two browsers into one of your own rooms, waits for video to genuinely flow between them, and tells you whether it worked — using the copy of the SDK sitting in

improvement

Sharpening the tools, not the product

Nothing in this one changes what you see. It changes what we see.

improvement

The complaints department had no phone line

Two fixes here, and they share a shape: something was configured correctly in one place, copied into a second place, and then the world moved and only the first copy noticed.

improvement

The other half of the call that showed nobody

Yesterday's note described a call that connects and then shows nobody, and fixed the part where several of our relay routes were unreachable from the outside. This is the other half, and it's the more interesting one.

improvement

The call that connects and then shows nobody

Some of you have had a call fail in the most useless way possible: it connects, the meeting opens, and then nobody is there. No error, no explanation. Usually it happened at work, on a locked-down office network, and you probably blamed your wifi. It wasn't your wifi.

improvement

When a customer leaves, they actually leave

Partners who resell CallSee.me can now tell us one of their customers is gone, and mean it. `DELETE` the tenant and it enters a 72-hour window, then the whole thing is erased — meetings, recordings, transcripts, files, members, settings. Not a deactivated flag, not a hidden row. If a partner's own licence agreement says the data goes, it goes on our side too.

improvement

One key, both jobs

We tell integrators to hold a single key: the one their backend uses to mint join tokens for their own users, which "also works everywhere the account key works". That sentence was true of everything except webhooks, where the same key got a flat *Forbidden*. So the one credential we document could either issue tokens or manage webhooks, never both — and the only key that could do both was the wide-open admin one we'd deliberately stopped handing out.

improvement

A key that opens exactly one set of doors

Yesterday's release let a partner sign its own customers up, each getting a real, separate account. Which immediately raises the obvious question: what else can that key do? Today's answer is "precisely what it should, and nothing adjacent."

improvement

Your customers are not each other's colleagues

Some companies sell CallSee.me inside their own product. Their customer books a meeting in *their* app, and a call happens — no CallSee.me logo, no account with us, often no idea we exist. Lovely for everyone, right up until you ask where those customers actually live on our side. Until today, the honest answer was "in one big room together": a partner's integration had no way to create a separate account per customer, so it wrote everything into a single one. Same meeting history. Same recordings. Same member list. Two businesses that have never met, filed as one.

improvement

One good hour is not a recovery

Every hour, robots call each other on CallSee.me. They join a real room on the real production service, wave at each other, check the picture actually arrived, and hang up. If anything is wrong, we hear about it before you do — that's the whole point of them.

improvement

A partner is not a customer, and now the database agrees

Some companies don't use CallSee.me directly — they build us into their own product, and their customers get video calls without ever hearing our name. We've had those arrangements for a while. What we haven't had is anywhere sensible to *put* one. So each partner got filed as if it were an ordinary customer, which meant every one of that partner's customers ended up sharing a single account: one pile of meetings, one pile of recordings, one participant list, no wall anywhere between one business and the next. It worked in the sense that calls connected. It was wrong in the sense that matters.

improvement

The alarm that had learned to cry wolf

Every hour, a small robot places a real video call to the real service and checks that it works. One part of that call has been reliably broken for a while — the fallback route we use for people on locked-down office wifi, from one particular vantage point. We know about it, we have measured it, it is written down, and the fix is a decision somebody has to make deliberately rather than a bug anyone can quietly patch.

fix

Asking production to do the actual thing

Not long ago we found five separate features that were finished, deployed, and completely dead. Not broken the way a bug is broken — every one of them passed its tests, returned a healthy status, and rendered exactly as designed. Each was simply missing one thing on the outside: a credential of the wrong sort, an address baked in when the app was built instead of read when it runs, a DNS record nobody created. From the inside, all five looked perfect. That is what let them survive.

improvement

Pointing at the good one

Housekeeping with a real consequence. When somebody building on our toolkit asks us which version they should be on, we answer with a number — and until this release that number was the one released yesterday, not the one released an hour ago. So a developer could ask, be told they were perfectly up to date, and still be sitting on the version with the empty-tile bug that the newer one fixes.

fix

The tile that was there and empty

Another one for the companies building their own video product on top of ours, and it is the same person who kept disappearing — from a different direction. Last time the fix made their tile appear at all. This time the tile appeared, correctly labelled, correctly marked as connected, and showed nothing. A rectangle with a name under it and no picture in it.

improvement

The grey circle that would not go away

This one is for the companies that build their own video product on top of ours. If somebody joined one of their calls with their camera switched off and then turned it on a minute later, they stayed a grey circle with their initials in it — not for a moment, but for the rest of the call, to everyone who had been in the room before them. Their camera was on. Their video was arriving. Nobody could see it.

improvement

Who is that, exactly

Names on video tiles have been playing a quiet game of hide and seek. In a call, only one person on your screen was ever labelled: whichever tile your mouse happened to be resting on. Move the pointer, and the name moved with it. Bring a third person into the room, watch the grid shuffle to fit them, and a name you had been reading for ten minutes would jump to somebody else's face. On a phone it was worse and simpler — a touchscreen has no pointer to rest anywhere, so nobody was named at all.

improvement

The code on the screen was not the code

If you have ever been in a call and read the room code out loud to someone, we owe you an apology. The panel showed it in capitals, which looks tidy and was wrong: codes are case-sensitive, so the version on screen opened nothing. The copy button always worked, which is exactly why this survived — the one path that behaved was the one nobody thought to distrust, and everyone who typed the code from the screen quietly concluded they had fat-fingered it.

feature

Who watches the watchman, and what to do when he's asleep

Last release added an alarm that places a real call on the live service every hour and checks that everybody can see and hear everybody else. It does that from two different places on the internet, on purpose, because a call that works from one network and fails from another is the most common shape of "it works for me". This release is about the discovery that one of those two watchers had been asleep the whole time.

improvement

The alarm that watches the room nobody resets

Last release fixed rooms that quietly got worse the more you used them, and it ended on a promise: a monitor that keeps checking the one thing a brand-new room can never show you. This is that monitor.

improvement

Rooms that forget the people who left

A room you keep coming back to used to get worse the more you used it.

improvement

The meeting room reaches the media server

Last release put a proper media server behind CallSee.me. This one connects our own meeting room to it.

improvement

Video that just works when you embed us

If you're building CallSee.me video into your own product, this is the release where that stops being fiddly. Until now, getting a working call through our SDK meant knowing that different ways of moving video existed, picking one, and setting an option most people never found. Ask anyone who's integrated a video API before and they'll tell you that's a strange thing to be asked. It's our plumbing, and it shouldn't have been your problem.

improvement

Two people who could see everyone except each other

Group calls are peer-to-peer: in a room of three there are six one-way connections, and every one of them has to work. The trouble with that shape is that a single broken connection is invisible from every other seat. Two people

feature

Branding belongs to the plan that pays for it

White-label branding has been on the Pro list for a long time, and until now nothing actually checked. Any organization could set its own logo, colours and typeface, which was generous of us and confusing for everyone trying to work out

improvement

Recover from a stuck initialization outage

Production went dark with HTTP 502s: the pods were healthy on the WebSocket port, but the HTTP server never started because it was gated behind a set of bootstrap tasks that could hang. When one of those tasks

improvement

E-signatures inside the meeting room

Meetings that matter usually end with something that needs a signature: a consent form, a contract, a witness statement, a closing note. Until now that meant stopping the call, opening another tool, and hoping everyone found the right PDF. v1.2.3 brings PDF e-signing into the meeting room itself, built on the same Yjs CRDT layer that already powers collaborative docs.

fix

Trust, clarity, and a sharper first impression

This release is a round of small, high-signal upgrades to the parts of CallSee you touch most: the lobby, the dashboard, the login screen, and the trust page. The theme is polish with a purpose — every fix removes a moment of friction or doubt.

improvement

Embed CallSee in your own product, properly

If you're building on CallSee — running your own app and letting *your* members talk to each other through our video stack — you've been doing it with a token-passthrough integration: your backend holds a key, mints a

improvement

Paid sessions: charge for your time

Some meetings are products. Therapy hours, tutoring blocks, legal consultations, expert calls — sessions where the host's time is the thing being sold. Until today CallSee could host those meetings but politely

improvement

Meetings that know when to go home

Free personal-room meetings have a 30-minute limit, and until now the timer enforcing it lived in the memory of whichever server happened to greet the first participant. If that server got recycled mid-call — routine

improvement

Knock, knock. Who's allowed?

Private persistent rooms got a proper front door. Before, "knock to enter" was mostly a polite suggestion the browser made on its own. Now it's enforced on the server: when an org member knocks on a private always-on

security

Two doors that were quietly ajar

Second security sweep of the day, and this one found two doors that looked closed but weren't. The first: we fixed an access-control gap so persistent rooms — the always-on spaces an org keeps around — now

security

Locks on every door, and a way through the firewall

This one is mostly the security team quietly walking the building and checking that every door actually locks. Magic links are now strictly single-use, defeating replay. Single sign-on now requires a verified

security

v1 API ships, first-run polish, security backfill

The headline is the v1 REST API. Notes, pins, and files all got proper public endpoints under `/api/v1/meetings/:id/*` — the three shipped on main right after v1.1.57's release cut, so this is the first prod build that exposes them. Notes are atomic. Pins are a

security

Security hardening + admin UX overhaul

The headline is security. A security audit identified and fixed an access-control issue and a server-side request-handling issue in URL previews. Both are patched and covered by regression tests. An automated auth-coverage check surfaced and closed several additional

fix

TURN/TLS on 443 + build fix

v1.1.53 never actually shipped. A build-configuration regression blocked the previous release; corrected so the database config loads correctly in the production image.

improvement

SDK 0.2.3: actually-correct ESM resolve + publish guard

0.2.2 renamed the dist outputs (`dist/index.js` → `dist/index.cjs`, `dist/index.mjs` stayed) to match what each package's exports map advertised — but I only updated the `require` side. `module` and `exports['.'].import` still pointed at `dist/index.js`, which no

fix

SDK 0.2.2: dist filenames match package.json exports

Hojt's first `npm install` of `@callsee/*` hit a packaging bug. Each package's `package.json` advertised:

improvement

Readable kiosk-mode control bar

Kiosks live across a reception desk or at the back of a meeting room. The control-bar buttons under `?mode=kiosk` were already sized for distance (64×64 with 32px icons) — the labels weren't. `text-xs` (12px)

improvement

Pre-join card no longer stretches

The pre-join `Gå med i mötet` card sat in a flex-row beside the camera preview. Default `align-items: stretch` made the card grow to match the preview's `aspect-video` height (~326px on a normal width)

improvement

Readable connection-status badge

The center-screen `Ansluter` (Connecting) badge in the meeting view sat on a 15%-translucent amber backdrop with same-hue text and border. On amber wind-down backgrounds — or any tinted backdrop — that

improvement

Structured logging for signaling side-effect failures

Improved reliability logging so transient backend errors during a meeting (e.g. a brief database hiccup) are captured in a structured, queryable form instead of silently dropping a webhook or billing timestamp.

feature

TURN: comma-separated URLs for TCP/TLS fallback

We added support for TURN over TCP/TLS so calls work on networks that block UDP entirely — corporate firewalls, hotel WiFi, etc. This release makes the relay API flexible enough to advertise multiple relay URLs

fix

Cluster-wide WS client metadata

The sibling fix to v1.1.44. In some multi-server scenarios a guest could be left waiting in the lobby because the approval prompt wasn't reliably delivered — the org-member check that decides who can approve

improvement

Cluster-wide WS connection cap

Our per-IP WebSocket connection limit wasn't enforced consistently across our infrastructure. Reworked it to apply a single correct limit globally, so a single client can no longer open more connections than

feature

SDK 0.2.1: live event subscriber

Hojt's Past Calls panel polls `/api/calls/channel/{id}/past` today because they have no other way to know a decision was recorded or a pinboard item was added. The server-side SSE endpoint (`GET /api/v1/events/stream`) has been live for a while; 0.2.1 ships

improvement

SDK 0.2.0: onJoin / onError callbacks

Hojt's React-component pivot needed lifecycle callbacks beyond `onLeave`. Today they get a silent black box on token failures and have to poll their own backend to learn when the meeting actually connected. Two new props

improvement

Self-Hosted Private npm + Version-Aware SDK

Hojt is migrating off the iframe to a React-component embed. We didn't want a public-npm dependency, so we stood up a private package registry hosting only our `@callsee/*` SDK packages, so the SDK never depends on

fix

Self-View in Narrow Iframes

Hojt reported that callsee.me's iframe finally loaded after the v1.1.38 embed-origin fix, but their self-view disappeared the moment they joined a meeting. Pre-join camera worked, in-meeting camera vanished.

fix

Iframe Embed Actually Works

The iframe embed allow-list shipped in v1.1.37 looked correct from every angle except the one that mattered: integration partners still got a white page. Partner iframes were still being blocked by a server-side request-routing bug in our embed-policy lookup. Fixed how

improvement

TURN for Guests, Iframe Origin Wildcards, Duplicate-Meeting Guard

Some peer-to-peer calls were quietly falling back to STUN-only and failing behind symmetric NAT. Two bugs were stacked. First, the TURN credentials endpoint required a JWT cookie — guests joining via `/meeting/[roomCode]` got a 401 and never received TURN at all. It now

feature

Webhook Wiring and Visual Polish

Two new webhook events (`decision.recorded` and `pinboard.item.added`) now actually fire. They were declared in the schema for a while but never `publishEvent`d — so anyone subscribed was getting a quiet

improvement

Compliance Housekeeping

A tidy-up pass on legal and privacy surfaces. Billing UsageEvents now get purged after seven years — matching Swedish bookkeeping law retention without letting them linger forever. The ToS now carries a clickable link

improvement

PiP Mode and Embed Hardening

The video meeting UI is now fully responsive to its container size. When callsee.me runs inside a 340x192px PiP panel (or any iframe narrower than 400px), it automatically switches to a stripped-down layout: single speaker

improvement

No Cookies in Embed Mode

Third-party cookie restrictions in modern browsers mean an iframe can't reliably set cookies anyway — so when `?embed=true` is in the URL, we now skip the cookie consent banner entirely and return `false` from `hasPreferenceConsent()`. No device preference cookies, no guest name cookies. The meeting still works fine without them; device selection just won't remember your last pick across sessions.

improvement

Streamlined Embedded Lobby

When a partner like Hojt embeds a meeting via iframe with `?displayName=...`, the pre-join screen now skips everything the partner already handled: no name input (the name came from the URL), no privacy/terms text (the parent app has its own), and the button says "Join" instead of "Request to Join." Most importantly, embedded guests join directly without the WebSocket approval flow — no waiting in the lobby.

feature

Partner Pricing Tiers and Embed Policy

Two features in this release, both driven by the Hojt partnership.

fix

Real-time Broadcast Fix and Webhook Auth

This one was a production incident fix. A messaging-layer misconfiguration was silently dropping about half of cross-server real-time broadcasts. Fixed so signaling is reliably delivered again.

improvement

Screen Sharing and Embed Events

The big addition here is media-server (SFU) screen sharing. Previously, screen sharing was peer-to-peer only, which meant it degraded fast with more than 3-4 participants. With our media server (SFU), screen shares now route through the SFU, so a 20-person meeting gets the same crisp shared screen as a 1-on-1.