The full breakdown — every feature, no roadmap items.
For buyers: this page reads like a changelog. If you want the short version — the ten reasons that matter without the engineering detail — jump to Top 10 reasons →. For engineers / evaluators: the list below is the entire feature set as of today, organised by area. The product runs entirely on your own Windows + IIS server — for organisations that already own their telephony and don’t want to send their calls through a SaaS cloud just to add browser meetings.
The meeting itself.
Video, audio and screen — the table stakes. Built directly on the browser's WebRTC stack with mesh topology, no media server involved.
HD video + audio
1280×720 native; per-track audio echo cancellation, noise suppression and AGC enabled by default. Camera and microphone pickers in settings.
Always-onScreen sharing
Full desktop, single window or browser tab. Auto-spotlights the sharer; auto-reverts to camera when stopped.
All major browsersFront / back camera flip
Mobile-only toggle. Switches between selfie and rear camera on iPhone / Android with a single tap. Other participants see the change seamlessly.
MobileSpotlight one tile
Click the expand icon on any tile → it goes large, others become a thumbnail strip. Auto-spotlight on local screen share. Auto-revert on stop.
UXPicture-in-picture (both kinds)
Standard PiP — single video pops out. Plus Document PiP on Chrome 116+ — the entire meeting UI (grid + chat + controls) floats as a resizable window.
Chrome 116+Mesh topology
Up to ~6 participants in a single full-mesh call. Every browser sends to every other browser directly; no server in the data path; bandwidth scales with N-1.
P2PTalk, type, point, share, react.
Once the call is up, everything else flows over WebRTC data channels — encrypted end-to-end, never relayed by any server.
In-meeting chat
Side panel on desktop, full-screen on phone. Markdown-safe text rendering. Coloured pills per author. Unread badge. End-to-end encrypted alongside the audio and video.
EncryptedP2P file transfer
Drag-and-drop into chat; chunked over the data channel; live progress bar; receiver downloads a real file. Up to 1 GB per file. Never touches the server.
PrivacyRemote pointer
Move your cursor over any tile; everyone else sees a labelled arrow at the same spot. Click flashes a ripple. Touch supported. Tile-local; no input injection.
CollaborationSticky notes on screen share
Double-click any tile in sticky mode → colored note appears at that spot. Editable, author-tagged, timestamped. Synced across all peers.
Demo / trainingReactions + raised hand
Six emoji reactions float up over the sender's tile and dissolve. 🤚 raise-hand sets a waving badge with auto-announce in chat.
UX polishLocal meeting recording
Composite canvas of all tiles + AudioContext-mixed audio → WebM (VP9 + Opus). Saved straight to the recorder's machine. Nothing uploaded.
Local-onlyShared whiteboard
Fullscreen canvas overlay everyone can draw on — pen, eraser, five colours, undo, clear. Strokes sync over the same chat data channel; no extra server endpoint.
Synced strokesBreakout rooms
Host splits the room into 2–4 groups for 2–30 minutes. Each peer reconnects to their assigned sub-room. Switch between groups or return to main with one click. Late joiners can pick from a live list.
Server-assistedWhat makes this a CodeB product.
The codeb.io thesis applied to conferencing: no third-party cloud, no telemetry, no data ever leaves the customer's network unless the customer explicitly routes it externally.
End-to-end DTLS-SRTP
Media keys are negotiated peer-to-peer at call setup. The server cannot decrypt; even a TURN relay only sees ciphertext.
WebRTC standardLockable rooms + knock-to-join
Lock the room → new joiners are held in pending. Existing participants admit or deny. Strangers never reach the call without explicit consent.
Server-side gateForensic-grade signed recording
Every recording ships with a sidecar JSON: SHA-256 of the file, ECDSA-P256 signature, participants list, speaker-turn timeline. Tamper-evident.
Audit-readyRecording-consent gate
Click Record and every other peer gets an Allow / Deny prompt. The recording can't start until everyone agrees. Each decision is logged into the ECDSA-signed sidecar — cryptographic proof of who consented when.
ComplianceVerified by CodeB badge
Participants who join from a workstation running Credential Provider V2 show an amber shield next to their name. Visible identity attestation in the meeting itself.
CP V2 integrationTime-limited TURN credentials
If the relay is in play, credentials are minted per session and expire automatically after one hour. No static password is ever embedded in the page source for an attacker to harvest.
Short-livedOn-prem Windows TURN
CodeBTurn runs as a Windows Service on the customer's LAN. No Docker, no Linux dependency. Stays on-prem; air-gap deployable.
Windows nativeSmall things that add up.
The hundred details that make the difference between a meeting tool you use because you have to, and one you actually enjoy.
Auto-spotlight on speaker
Whoever speaks loudest auto-becomes the spotlight tile. Short cooldown prevents flicker. Toggleable.
OptionalConnection-quality bars
Per-tile signal bars track round-trip time, packet loss and bitrate. Colour-coded so you can spot a struggling peer at a glance.
DiagnosticAuto-reconnect
If the network blips, the call recovers itself: a brief “Reconnecting…” banner appears, peer connections are re-established, and the meeting resumes without anyone needing to rejoin.
ReliabilityAudio elevator brake
Sudden volume spikes on any remote stream are softened automatically and the speaker's tile gets a discreet ?! badge so nobody is blown out of the call.
Auto-appliedPer-tile volume sliders
Hover any remote tile → small vertical slider top-right. Independent volume per participant, 0–200%. Local to your tab, doesn't change anyone else's audio.
Per-participantIdle camera dim
When your tab loses focus, your outbound video drops to a low bitrate. It comes back full-quality the moment you return. Saves bandwidth for everyone else without a manual mute.
Zero-configResponsive layout
Single tile, 2-column, 3-column grids based on participant count. Phone-friendly controls. Safe-area-inset aware for the notch.
All devicesQR code join
The landing page generates a live QR for the room URL as you type. Generated locally in the page — no third-party service involved, works fully offline.
Self-hostedKeyboard shortcuts
M mute · V camera · S share · C chat · E spotlight · H hand · P PiP · Space push-to-talk.
Power usersPersistent preferences
Name, device picks, mirror, push-to-talk, auto-spotlight, pointer, blur, join-muted, join-cam-off — all remembered across browser sessions. Stored locally; never sent to any server.
Local-onlyBackground blur
On-device segmentation: you stay sharp, your background goes soft. Runs entirely in the browser; no image ever leaves your machine for processing.
Optional · GPULive device + name rename
Switch microphone, camera or your display name mid-call without dropping the connection. Peers see a system message and updated tile label.
Mid-callBandwidth adaptive ladder
Outbound video steps down per recipient through 720p → 480p → 360p → audio-only as link quality demands. Each peer gets the best tier their connection can carry — the slowest person doesn't pull everyone else down.
Per-peerRoute + quality badge
Each remote tile carries a tiny chip — LAN · 1080p, P2P · 720p or Relayed · 480p — so you can confirm the link is truly peer-to-peer (or see when it's not) at a glance.
Phones are first-class participants.
A self-hosted WebRTC ↔ SIP gateway turns a meeting room into a callable destination — or a phone number into a meeting participant. Drop a Call-us button on any web page; the recipient picks up on their normal phone and lands in a CodeB meeting alongside everyone else.
WebRTC ↔ SIP bridge
A small on-prem service that registers as a SIP extension on your PBX or trunk provider. When the bridge dials a number, the answering phone joins the meeting as a normal audio-only participant. Standard codecs on both sides; no third-party transcoding service.
On-premOne-click call from any web page
Drop a single URL on a support page, contact form or signature: when the visitor opens it, the bridge dials your team's phone automatically and the visitor joins the same meeting room from their browser. No installs, no plugins, no third-party redirect. Perfect for “Talk to sales now” buttons.
EmbeddableSecret alias IDs keep real numbers off public pages
Every callable destination gets an unguessable 64-bit alias. Public URLs use the alias — ?dial=n_a3b7c2d4e8f1a9b3 — so the real phone number never appears in your site source, email signatures or printed material. Aliases can be rotated without changing the destination.
Bring-your-own SIP trunk
Works with any standards-compliant PBX or trunk provider — consumer routers, on-prem PBX appliances, hosted ITSPs. Credentials live in the bridge's local config; nothing routes through a third-party intermediary. Your call records belong to your trunk provider.
No vendor lock-inMulti-trunk with priority & failover
Define multiple trunks, give each a priority. A dial uses the highest-priority trunk that has free capacity; if the chosen trunk is busy or unreachable, the bridge transparently switches to the next. Per-trunk concurrent-call caps let single-line residential trunks and high-density SIP-trunk providers coexist in the same setup.
High availabilityPer-number routing rules
Define rules like “extension 610 always dials via the office PBX” or “everything in +356 goes via the Malta trunk”. Wildcards and E.164 prefixes both supported. Useful when different destinations need different carrier paths for compliance or cost.
Per-call dial prefix per trunk
Each trunk has an optional dial prefix (e.g. *31# on European carriers) prepended automatically to E.164 destinations. Use it for per-call caller-ID suppression, premium-route opt-out codes, or any carrier-specific dial signal you want applied uniformly on every outbound call through that trunk. Internal extensions are never prefixed.
Strict number whitelist
The bridge only dials numbers explicitly enumerated by the operator. An attacker who finds a dial URL still can't redirect it to a premium-rate destination — the whitelist is the gate, the alias ID is just a shortcut to a row in it.
Zero-trust dial-outGeographic prefix restriction
Operator-configurable E.164 prefix allowlist. Ship a deployment that can only dial European destinations (or any subset you define). Plus a blocklist for premium-rate ranges that always wins, even if a whitelist entry accidentally includes one.
CompliancePer-call fraud caps
Hard limits on concurrent outbound calls, max call duration, daily call-count per room and per requester IP. Even with the whitelist breached, an attacker can't run up an unbounded carrier bill before the cap stops them.
Toll-fraud guardE.164 + PBX extensions both work
Dial an international number, a residential-router internal extension, or a PBX dialplan number. The bridge normalises the format and applies the right SIP user-part for the chosen trunk — one consistent dial syntax regardless of carrier.
Format-agnosticText-to-speech auto-reply
Answer specific inbound callers with a pre-recorded message instead of ringing the CodeB Webphone. Define rules in config: blacklist a nuisance number with “this line is closed, goodbye”, send an after-hours greeting on a specific DID, or play any canned response. The bridge handles the SIP answer, plays the message, and hangs up — no human picks up.
Rule-drivenCountry-aware language responses
Match callers by country code — ISO-2 (CN, DE, IL), country name (China), or raw E.164 prefix (+86). Play a different language per country: “I do not speak Mandarin” for +86 callers, German hours announcement for +49, English fallback for everyone else. Numbers without an international prefix don't match country rules, avoiding false positives on domestic-format caller IDs.
Local TTS engine, no cloud
Uses Windows’ built-in speech engine (SAPI) by default — no API key, no external service, no data leaves the host. Voices are configurable per deployment; install the German voice pack and your “Anrufer nicht verfügbar” sounds native. The auto-reply pipeline pre-renders every rule to G.711 at startup, so the very first matching call answers in milliseconds with zero per-call TTS latency.
Privacy-safeBounded, abuse-resistant playback
Each auto-reply has a hard per-rule duration cap, counts against the global concurrent-call limit, sends 180 Ringing before answering so carriers' jitter buffers warm up, prepends a configurable lead-in silence so no syllable gets clipped, and bails immediately on caller CANCEL. A flood of blacklisted callers can’t monopolise the trunk — cap hits, carrier rolls to voicemail / next-step cleanly.
Safe-by-defaultA voice AI that actually picks up.
Point a number at CodeB, pick the real-time voice mode, paste a system prompt. The next inbound call is answered by a real-time voice AI that speaks any language, follows the script, takes messages, transfers to a human softphone when the caller asks, and emails you the transcript when the call ends. Sample industry: hospitality — one front desk, three personas (reception, restaurant, spa), 24 hours a day. Browse every virtual number configured on this host in the virtual numbers directory.
Real-time, not record-and-respond
Full-duplex audio over the SIP leg the caller dialled. Hears the caller as they speak, can be interrupted mid-sentence, replies with sub-second latency. No “please wait while I think” pauses. The real-time voice backend is pluggable per deployment.
Real-time voiceAny language, on the fly
Detects the caller’s language and replies in kind. Switches mid-call if the caller switches. The script can pin a default greeting language or let the model decide.
MultilingualOne persona per number
Each virtual number gets its own system prompt, voice, opening line, and warm-up delay. A hotel can run reception, restaurant and spa on three numbers — same AI engine, three personalities, one deployment.
Per-number configWhitelisted transfer to a human
The receptionist decides when to transfer using a structured transfer_to_user tool. Registered SoftPhones go direct via SIP REFER; external phone numbers are gated by the per-tenant number whitelist and refused fail-closed when off-list. FraudGuard re-checks on the loopback for defence-in-depth.
Self-terminating — with reason
A hangup tool lets the model end the call itself with a logged reason (caller said goodbye, abusive, voicemail loop). Reasons land in the transcript and CDR so you can spot patterns — useful when tuning a prompt against real call data.
One room per caller
Browser dial-in URLs can use room=random to mint a fresh isolated room name per session. Two visitors landing on the same link never share a room, so the AI never accidentally hears the previous caller’s side of the conversation.
Delegate prompt editing
Each virtual number lists an editors address book and exposes a per-number editor URL you can share with that team. The duty manager rewrites the script for the night without touching admin, the maître d’ tweaks the restaurant persona. Visibility — admin / signed-in / anonymous — controls who can see the row in the public directory.
Delegated configTranscript + summary by email
Every call ends with a full transcript and a one-paragraph summary, sent to the per-number recipient list. Reads like a human took notes. Nothing else is retained on the server by default — no silent recordings.
No silent recordingsAlways answers — TTS fallback
If the configured provider credentials are missing or the model is unreachable, the bridge auto-falls back to a server-side TTS auto-reply so the caller never hits dead silence. The CDR records the fallback so you know it happened.
ResilientFull feature page with the hospitality sample setup, configuration walkthrough and FAQ → ai-receptionist.html
A phone that lives in the browser.
Beyond ad-hoc meeting rooms, the same stack powers a registered identity that rings on incoming calls — from teammates or the PSTN trunk. Install it as a desktop app, leave it open, pick up calls all day. The phone you actually use, not a webpage you forget about.
Installable as a desktop app
The CodeB Phone surface installs as a Progressive Web App on Windows, macOS, Chromebook and Android. Standalone window, dock/taskbar icon, launches with the OS. Browser tab discard can't kill it, and it stops cluttering your tab bar.
PWASelf-updating
When a new build ships, the open phone notices within minutes and shows a small “Update available — reload” chip. One click rolls forward to the new version with no manual cache clears or admin involvement. Mid-call updates are deferred until the user is ready.
No IT touchInbound calls ring your tab
Register as a user (“anna”, “sales”, “reception”, …); the SIP bridge routes incoming PSTN calls and teammate calls to your tab with a familiar ringer, OS-level notification and accept/decline. Pick up — the meeting room opens with the caller already there.
Always-onBrowser-to-browser direct calls
Type a name in the Call widget → that teammate's phone rings, peer-to-peer, no SIP trunk, no carrier minute. Type a number instead → the bridge dials through your configured trunks. One control, two backends, no mode switch.
Zero-cost intra-teamAuto-recovery from trunk loss
If a PBX or SIP trunk reboots or drops off the network, the bridge notices, tears down the stale registration and re-registers within roughly a minute. Inbound calls resume without restarting the service. Surfacing in the trunk-log so operators can see exactly what happened.
Self-healingOperator visibility
Built-in admin views show recent inbound and outbound calls, who routed where, and live trunk REGISTER state — useful when a caller says “I rang and no-one picked up” and you need to confirm whether it ever reached the bridge. All on-prem, no external dashboard required.
On-prem opsDial a camera. See and speak.
An ONVIF security camera registered with the bridge appears in the CodeB Phone Call widget under a friendly name. Dial it — the camera streams its live feed straight to your browser, and the talkback button pushes your microphone back down the camera’s built-in speaker. Useful for door stations, reception cameras, warehouse intercoms, livestock and remote-site monitoring. Camera dial-ins require a signed-in user — anonymous connections are rejected at the signaling layer.
Try the live demo: create an account (or sign in if you already have one), open CodeB Phone, then dial camera — that’s our public test alias pointing at a real ONVIF camera. You’ll see the live feed and can try talkback through its built-in speaker. Anonymous sessions cannot dial cameras.
Call a camera by name
Configure each camera with a short alias (“camera”, “reception”, “loadingbay”) in your bridge config. Type that name into the Call widget → live H.264 video opens in a dedicated viewer window, no extra app, no plugin. Our public demo is reachable simply as camera — sign in first, then dial it from the CodeB Phone. Camera names are reserved system-wide — nobody can register a CodeB Phone identity that would shadow a camera route.
Two-way audio via ONVIF backchannel
On cameras that expose the ONVIF backchannel profile (most Reolink, Hikvision, Dahua, Axis indoor units with built-in speakers), a single click on the talkback button routes your microphone back through the camera’s speaker. Push-to-talk through a door station, calm a barking dog, give a delivery driver instructions — without leaving the browser.
TalkbackDirect media, server stays out of the path
The IIS signaling endpoint proxies only the SDP offer/answer exchange so the camera’s HTTP credentials never reach the browser. Once the call is up, WebRTC media flows directly between the browser and the on-prem camera relay — no transcoding service, no third-party relay, no per-minute media bill. The server CPU stays at idle even with several cameras live.
Zero media transitWorks with standards-compliant cameras
Cameras connect via RTSP / ONVIF — the same protocols every prosumer IP camera already speaks. No vendor SDK, no cloud account, no firmware lock-in. Tested with Reolink and Hikvision; any camera that streams a Main/Sub RTSP profile with H.264 video and (optionally) AAC or G.711 audio fits in.
No vendor lock-inCamera credentials never leave the server
The bridge holds the camera’s HTTP Basic credentials in its local config and signs every upstream call itself. The browser only ever sees a friendly name and an SDP answer — never an RTSP URL, never a password, never a hostname. Rotate camera passwords on the device, update one config entry, done.
Auth-proxySame surface as your phone calls
You don’t learn a new tool. The camera viewer reuses the CodeB Phone’s end-call button, microphone mute, speaker mute, and ICE handling. Open and close cameras as casually as picking up the desk phone — same muscle memory, same look, same on-prem privacy guarantee.
One surfaceSign-in required — no anonymous viewers
Camera dial-ins are gated behind a CodeB Conference account. A visitor who hasn’t signed in cannot dial camera, reception or any other camera alias — the signal handler rejects the call before the bridge is ever contacted. Every camera viewing is attributable to a named identity in the audit log, and operators can revoke a user’s access by disabling the account — no per-camera ACL maintenance required.
What runs where.
A handful of small pieces. Most are optional. None of them ever sees your video.
IIS signaling
A small WebSocket endpoint on the IIS side relays room joins, SDP offers/answers, and ICE candidates. The server stays out of the media path — it only helps peers find each other.
TinyCodeB TURN (optional)
An on-prem STUN+TURN relay that handles users behind strict corporate firewalls or symmetric NAT. Single-file install, runs as a Windows Service. Stays inside your network — no third-party relay involved.
OptionalCodeB SIP bridge (optional)
A Windows Service that registers as a SIP extension on your PBX/trunks, bridges between WebRTC browsers and the carrier audio path, and keeps itself alive through reboots and network drops. Only needed if you want to talk to phones; without it the platform is pure browser-to-browser.
OptionalCodeB camera relay (optional)
A small RTSP → WebRTC translator that runs on the same host as the bridge and connects to your IP cameras over the LAN. Only needed if you want to call cameras from the phone surface; without it the platform is purely people and phones.
OptionalBrowser only — no client install
Every participant joins from a regular HTTPS page. Camera, mic, screen share, file transfer, recording — all happens in the user agent. Optional install for the always-on phone surface; everything else is just a URL.
Zero installMany tenants, one install.
Operators run a single CodeB instance and host many independent customers on it. Tenant identity is the request domain — no shared accounts, no cross-tenant routing, no per-customer rebuild. Add a tenant by pointing a new hostname at the same host.
Tenant = request domain
A request for phone.acme.com routes to the Acme tenant; phone.contoso.com to Contoso. The signaling endpoint, the SIP bridge and the CDR writer all key off the Host header. No shared user table, no cross-tenant collisions.
Per-tenant everything
SIP credentials, trunks, FraudGuard caps, AutoReply rules, CDR files, registered softphones — all scoped to the tenant key. Tenant A’s misconfigured trunk can’t accidentally bill Tenant B; Tenant A’s rooms can’t be joined from Tenant B’s URL.
IsolatedDrop-in tenants
Stand up a new customer by adding a hostname — DNS A record + IIS host binding + tenant config block. No schema migration, no restart of other tenants, no downtime for the existing customer base. The instance keeps serving the others while the new one warms up.
Zero-downtimeHosting-friendly economics
One Windows host, one IIS site, one SIP bridge process — many tenants behind it. The marginal cost of adding a customer is the cost of a hostname.
OperatorNo accidental cross-talk
Storage paths are tenant-prefixed: App_Data/<domain>/appsettings.json, App_Data/<domain>/logs/, App_Data/<domain>/logs/cdr/, App_Data/<domain>/sip-credentials/. A bug or misconfiguration in one tenant can’t reach into another tenant’s data — the prefix is enforced at the file-system layer, not just convention.
Single sign-on, built in.
A full OpenID Connect identity provider runs inside CodeB. Sign-in lives on every page: a Sign in with CodeB button on the landing form prefills the participant name and stamps the in-call tile with a verified badge; the same button on the SoftPhone PWA auto-registers the right SIP identity; admin pages and any third-party RP (Nextcloud, custom apps) all federate against the same user database. See the OIDC details →
OpenID Connect Core 1.0
Authorization Code flow with PKCE (S256), RS256-signed JWTs, discovery per RFC 8414, JWKS per RFC 7517. Anything that speaks OIDC plugs in — point it at /.well-known/openid-configuration and go.
Cookie-free by design
No session cookie. No tracking cookie. The login form mints the auth code directly, the callback exchanges for tokens, and the tokens live in per-tab sessionStorage — gone when the tab closes. If you advertise cookie-free, you stay cookie-free.
One credential store
Sign-in reuses the same HA1 hash your SIP softphones use. Plaintext password never reaches the server — the browser hashes it before posting. One user record drives both voice and identity.
No duplicate usersPer-tenant RSA keys
Each tenant gets its own 2048-bit signing key, generated on first need at App_Data/<tenant>/oidc/private-key.xml. Tokens minted for tenant A do not verify against tenant B. Rotate by deleting the file and recycling the app pool.
Roles, server-enforced
Three roles out of the box: admin, user, siponly, guest. The role travels in the JWT as a custom claim and a standard groups entry. Admin pages re-check the role on every server request — client-side checks are UI only.
Integration guide
Adding CodeB sign-in to any app that speaks OIDC takes about 10 minutes. Generic OIDC guide · Nextcloud · WordPress.
Documented