Meshbell EN · FR · ES · DE · IT · PT · EL Get the iPhone beta

Nonprofit · Free · Not a replacement for official emergency services

Documentation

Meshbell is a neighborhood scale emergency instrument. Verification is the substrate, not a feature. This page says how, and where the edges are.

Overview

A hazard warning in Meshbell is a small signed record. It is named by the hash of its own bytes, signed with a device key, and never altered. A correction is a new record that points at the old one, which is what lets a warning and its correction travel together and lets any device re-check anything it receives.

Your phone has two links, and neither one needs the internet

This is the whole connection model, and the app's Connect tab is where you see both of your links. The third row below is not a phone link at all: it is what the radios do between themselves, one hop further out.

MediumWhat it reachesHow it starts
Bluetoothfrom your phoneA pocket radio: a companion LoRa node in your bag. This is the only way a phone gets on the air, because no iPhone has a LoRa radio inside it.You tap Connect. A scan costs battery and takes an exclusive claim on the radio, so a person starts it, never the app.
Wi-Fifrom your phoneA neighborhood bridge: one always-on box on the local network, holding the record and serving it to phones and browsers.Automatically at launch. The app looks for a bridge on whatever Wi-Fi you are on, and there is a manual address field for networks that block discovery.
LoRaradio to radioThe long leg. Two prepared people with pocket radios reach each other across the blocks with nothing in between; every additional radio repeats it onward.Nothing on the phone starts it. Your phone never speaks LoRa, so this leg begins the moment two radios are tuned to the same channel, whether a phone is attached to either of them or not.

The whole chain, end to end: your phone over Bluetooth to the pocket radio in your bag, that radio over LoRa across the blocks to another radio, that radio into a bridge, and the bridge over Wi-Fi to every phone and every browser on the neighborhood network.

Both links feed one journal and one keyring. A record that arrives over the air and one that arrives over Wi-Fi land in the same log and get the same check. Turning the radio off does not stop bridge reception, because they are separate paths to the same place.

Everything above the network is built so that losing a connection, a server, or a model costs you an annotation, never the alert.

Which of these are you?

There are three ways to be ready, and the rest of this page is written for all three. Find yours, then read its stations first.

Just a phone
Free, and enough to receive. You hear what a bridge in range or an internet connection can hand you, and nothing is on the air until someone near you has a radio. Read the overview and working offline, then the ways to prepare on the front page.
A pair of radios
About $30 each, one in your bag and one in a neighbor's. That is the long leg: the two of you reach each other across the neighborhood with no cell, no internet and nothing in between, and every radio anyone else adds repeats it further. Read radios and hardware and radio bands by region.
A bridge host
One always-on box, ~$50-80, that turns the neighborhood's own Wi-Fi into a communications center any browser can join, with no app and no account. Read setting up a bridge, what a bridge put on the air and more than one bridge.

The trust model

Meshbell keeps two questions apart, because they are different facts and blurring them is how bad information spreads.

QuestionWhat answers itWhat it can say
Which record is this, and is it intact?The content address and the signature check, both run on your devicebound · preview · tampered
Who signed it, and can I check?The keyring on your deviceverified · could-not-check · forged

The second axis is deliberately three valued. A forgery, checked against a key you hold and failed, is not the same fact as an unknown key, which is no way to check yet. Collapsing them into one word "invalid" would hide exactly the distinction a person needs. A message is stored as trusted only when the keyring says verified.

Verified off the air, with no prior copy

A short radio frame is a preview: a pointer at a record, shown but never trusted and never used to invent a body. A record can also be sent in full as a self-authenticating envelope, split across several frames and reassembled on the far side. A device that has never seen the record before can then rebuild it, re-derive its content address, and check its signature, reaching a verified verdict on a pure radio neighborhood with no internet anywhere in the loop.

Frames arrive unauthenticated over LoRa, and the fragments of a split record are unsigned in transit. Only the reassembled record is verified. An incomplete group says so and stays a preview.

The instruction firewall

The one thing an emergency app must never do is turn a rumor into an order. Meshbell enforces that in the structure of the code, not by review discipline.

The promise, in one line. The app never launders a rumor into an instruction, and that sentence is a property of the code rather than a mission statement.

The coordination layer

Verified alerts answer what is happening and whether you can trust it. A neighborhood in an emergency also has ordinary logistics: who is accounted for, where the shelter is, who has a generator. Meshbell carries a second, deliberately separate layer for that work, native in the app's Neighborhood tab and in a browser for anyone without the app.

This layer is unverified by design. It is not content addressed, not signed, and not part of the alert rail. It is mutable shared state that neighbors write and edit, so treat it like a note taped to a door. The instruction firewall still holds: nothing here can render as an official instruction, and the trust model above governs alerts only.

What it holds

SurfaceWhat it isPrivacy shape
Safe roll-callOne tap "I'm safe" check-in. Everyone sees an aggregate count against an approximate household total.No names, addresses or locations, and no roster. The count is withheld until a handful have checked in, so a single household cannot be inferred.
Resource listsShared, editable lists: shelter and warming, water and supplies, power and charging, and a self-listed who can help. Items can carry a place label.Anyone on the bridge can add or edit. Self-listed only. No one is added by someone else.
BoardShort posts tagged to a channel (info, offer, request, question) and windowed by recency, posted under a name you type.Whatever name you type. No account, no verified identity.
Printable snapshotA one page /coord/print render of the roll-call, the lists and the latest board, for when batteries die.The same aggregate only roll-call, so it is safe to tape to a physical board.

Why it is held apart

Mixing mutable neighbor notes into a signed, append-only alert log would break both. So the coordination store is its own thing: local network only, mutable, and served by the bridge beside the verified feed rather than inside it. An operator holds an admin token for housekeeping, such as clearing test data or pruning a runaway board, and the admin routes fail closed without it. Posting and checking in need no credential at all. The two layers share a screen, never a trust boundary.

Working offline

Degradation is the expected state, not an error. When a data path is down, Meshbell serves the last known good data labeled with its age, "as of 40 minutes ago", rather than a confident looking blank. The zero model tier, an old phone with nothing clever on it, is a first class product tier. An emergency app that only works on the newest hardware fails the people most likely to need it.

Reception continues while Meshbell is in the background, and iOS can relaunch it to hand back a radio connection after it has been closed. See listening in the background for what that does and does not cover. It has never listened when the phone is switched off, and it will not claim to.

Radios and hardware

Meshbell runs on your phone alone. Radios extend its reach when the network is down. A neighborhood mesh is built from inexpensive off-the-shelf LoRa hardware running the open MeshCore firmware.

PieceCostRole
A companion LoRa radio, for example a Heltec node~$30Your phone pairs with it over Bluetooth to send and hear bulletins. A companion serves one phone at a time. If another phone or app holds it, yours is told so plainly instead of spinning.
More radios around the neighborhood~$30 eachEach one is a hop, and each repeats a record once and then stops so the air stays clear. Three or more begin real multi-hop reach across blocks and ridgelines.
An always-on bridge, usually a Raspberry Pi~$50-80Holds a durable log and serves it over local Wi-Fi on port 4190. It will use an internet uplink when one exists, and it needs none.

US radio settings. Meshbell's reference bench runs 910.525 MHz, bw 62.5 kHz, sf7, cr 4/5, inside the license free 902-928 MHz band, with a 172 B companion link envelope. Always read your radio's configuration back before transmitting. The region default may be a band you are not licensed to use.

Radio bands by region

Your phone has no LoRa radio inside it, so it never touches the band. The radio's own firmware owns that setting. Meshbell reads the tuning back off the radio when it connects, prints it, and says plainly when the radio is not on the channel your region uses.

910.525 MHz is the North American station. Every region below has its own channel, placed inside the license free band that region allows. Where the MeshCore community publishes a recommended channel for a country, Meshbell adopts that channel and its settings exactly, so the MeshCore repeaters already standing there can carry Meshbell bulletins. Where the community has published none, Meshbell picks a channel that sits clear of the busiest part of the band.

RegionBandMeshbell channelDuty cycle or listen before talk
United States and Canada902-928 MHz910.525 MHzNo duty limit, so a bridge can beacon as often as it needs to. Up to 36 dBm, antenna included. This is MeshCore's own recommendation for the United States and Canada, so existing MeshCore repeaters here can carry Meshbell bulletins.
Europe and United Kingdom869.4-869.65 MHz869.618 MHz · sf8 · cr 4/810% duty cycle, about six minutes of transmit time an hour. Up to 29 dBm. The United Kingdom applies the same limits, so there is no separate setting for it. This is MeshCore's own recommendation for Europe and the United Kingdom, so existing MeshCore repeaters here can carry Meshbell bulletins.
Czech Republic869.4-869.65 MHz869.432 MHzThe same 10% duty cycle and 29 dBm ceiling as Europe, on a channel of its own. This is MeshCore's own recommendation for the Czech Republic, so existing MeshCore repeaters there can carry Meshbell bulletins.
Netherlands869.4-869.65 MHz869.618 MHzThe same 10% duty cycle and 29 dBm ceiling as Europe. This is MeshCore's own recommendation for the Netherlands, so existing MeshCore repeaters there can carry Meshbell bulletins. It shares Europe's frequency but runs the default sf7 and cr 4/5, so the two do not hear each other even on the same frequency.
Portugal869.4-869.65 MHz869.618 MHz · cr 4/6The same 10% duty cycle and 29 dBm ceiling as Europe. This is MeshCore's own recommendation for Portugal, so existing MeshCore repeaters there can carry Meshbell bulletins. It shares Europe's frequency but runs sf7 and cr 4/6, so the two do not hear each other even on the same frequency.
Australia915-928 MHz916.575 MHz · cr 4/8No duty limit. Up to 30 dBm. The band starts at 915 MHz here, so the North American channel is not legal. This is MeshCore's own recommendation for Australia, so existing MeshCore repeaters there can carry Meshbell bulletins.
New Zealand915-928 MHz917.375 MHzNo duty limit. Up to 30 dBm. The band starts at 915 MHz here too, so the North American channel is not legal. This is MeshCore's own recommendation for New Zealand, so existing MeshCore repeaters there can carry Meshbell bulletins.
Brazil915-928 MHz923.125 MHz · sf8 · cr 4/8No duty limit. Up to 30 dBm. This is MeshCore's own recommendation for Brazil, so existing MeshCore repeaters there can carry Meshbell bulletins.
Southeast Asia920-923 MHz921.875 MHz10% duty cycle in the strictest country of the group. Up to 17 dBm. One grouped setting for Thailand, Singapore, Malaysia and Indonesia, so check your own country before leaving a bridge running. The community publishes no channel for these countries, so this one is Meshbell's own, chosen clear of the busiest part of the window.
Vietnam920-923 MHz920.25 MHz · sf810% duty cycle. Up to 17 dBm, and the rules here move, so check the current ones before leaving a bridge running. This is MeshCore's own recommendation for Vietnam, so existing MeshCore repeaters there can carry Meshbell bulletins.
India865-868 MHz866.5 MHz1% duty cycle, about 36 seconds of transmit time an hour. Up to 16 dBm. The radio cannot hold itself to a limit this tight, so the bridge has to pace itself. The community publishes no channel for India, so this one is Meshbell's own, chosen clear of the busiest part of the band.
South Korea920.9-923.3 MHz921.4 MHzNo duty limit, but the radio has to listen before it talks. Up to 23 dBm.
Japan920.6-928 MHz924.6 MHz · bw 125 kHz10% duty cycle and a listen before every transmission. Up to 16 dBm. The wider bandwidth is what keeps a single burst short enough for Japan's rules.
Russia864-865 MHz864.5 MHz0.1% duty cycle, about 3.6 seconds of transmit time an hour, unless the radio listens before it talks. Up to 16 dBm.

Unless a row says otherwise, a channel runs sf7, cr 4/5 and bw 62.5 kHz. A row that follows a MeshCore channel carries whatever that channel uses, which is why several show a different spreading factor or coding rate, and Japan runs bw 125 kHz to fit inside Japan's rules. Two radios hear each other only when frequency, bandwidth, spreading factor and coding rate all match.

Radios come in two families, one cut for 902-928 MHz and one cut for 863-870 MHz, and between them they cover every region on this list, but China's 470 MHz band needs a different radio chip and a different antenna, so it is not a setting anyone can switch to.

Three regions are not ready. Japan, South Korea and Russia expect a radio that listens before it talks, and the MeshCore firmware does not do that yet, so those three stay off until it does. A region also carries a power ceiling, and power is a separate setting on the radio, so changing the channel is not the same as lowering the power. Always read your radio's configuration back before transmitting.

Setting up a bridge

A bridge is one always-on node in the neighborhood, usually a Raspberry Pi, that carries the verified feed and the coordination layer over local Wi-Fi so every neighbor's phone or browser can reach them with no cell and no internet. It is the second of the phone's two links: Bluetooth reaches a pocket radio, Wi-Fi reaches a bridge, and either one works with no internet at all.

The bridge's own Wi-Fi, so a neighbor needs nothing

With a second Wi-Fi adapter the bridge runs its own open network, named meshbell- and then your street. It is a dead end on purpose: it reaches the bridge and nothing else, not the house, not the internet, not the other phones on it. A neighbor needs no app and takes four steps. Join the Wi-Fi whose name starts with meshbell-. A page opens by itself, the way a hotel network opens its sign-in page; tap Continue. If the phone asks about the internet, tap Use Without Internet, because this network has none on purpose. If you close that page, open a browser and type meshbell.lan. Set the network up once with sudo ./install-ap.sh --interface wlan1 --ssid meshbell-oak-st.

If you are the host, one prepared neighbor

The installer ships inside the app and is exported straight off your phone, so nothing is downloaded. Unpack it on the Pi, run the install script, and it prints the address to hand out. The node comes up self contained: it serves the coordination screens, an installable web app for browser-only neighbors, a QR code of that address, and an admin view for housekeeping. It advertises itself on the local network as _meshbell._tcp, and the app does the finding. There is nothing to configure by hand and no account to create.

If you are a neighbor who has never heard of a mesh

Join the neighborhood's Wi-Fi and open the Neighborhood tab. The app looks for the bridge by itself and connects. When discovery needs a hand, it asks the plain questions, is this the right network and is the bridge awake, and offers a manual address field. If a computer can reach the bridge but this phone cannot, the two are almost always on different Wi-Fi networks.

The bridge delivers, it never decides. A bridge can pass a verified alert along, but it cannot make one true. Signatures are checked on your own device, and in a plain browser they are checked in that browser. A compromised or malicious bridge can drop or delay messages. It can never forge a trusted one. That is why the trust model lives on the phone and not on the node.

Listening in the background

The phone keeps the radio link while Meshbell is in the background, and iOS can relaunch Meshbell to hand a connection back after the app has been closed. Three things make that work together: the system preserves the Bluetooth connection, the app asks to be restored with it, and it remembers that you wanted the radio connected, so it can redo the handshake the firmware requires on every new connection.

The honest edge of it. iOS may still stop the app, and a companion radio serves one phone at a time, so a radio another phone is holding is not available to yours. Background listening also does not survive a phone that is switched off. What it does mean is that a bulletin arriving while the phone is in a pocket is delivered rather than missed.

What a bridge put on the air

Two facts that are easy to mistake for one: the radio accepted a message, and the message actually went out. The first is what a phone learns when it hands frames to a companion radio. The second is measured from the radio firmware's own transmit counters, and only a bridge reads those.

A bridge keeps a receipt for everything it transmits: what went out, who signed it, which link carried it, how many pieces it was cut into, the channel, and whether the counters confirmed it left the antenna. The app shows those receipts on the What went out screen when a bridge is connected.

There is no phone-side receipt, and Meshbell does not invent one. When you send, confirm or dispute a report from the app, it tells you the radio took your message and says plainly that it cannot confirm it went on the air. A flood packet has no addressee, so nothing acknowledges it. Claiming delivery would be the flattering answer, not the true one.

Plain text from other radios

MeshCore radios carry ordinary text messages between people who are not running Meshbell. A bridge can hear that traffic, and it keeps it strictly apart from the verified feed. It is marked unsigned, which is deliberately a different word from could not be verified: an unverified bulletin is a signed record whose key this device does not hold, while plain text carries no signature at all.

Channel messages carry no sender key, so a name typed inside the body is not an identity and Meshbell never treats it as one. This traffic is never stored, never appears in the verified feed, never counts toward corroborating anything, and can never become an alert. The bridge reports how much of it it has heard, and nothing more.

Radios that sign for themselves

A MeshCore radio holds its own signing key and the firmware will sign with it. A bridge operator can enroll a radio, after the radio proves it holds the key, and from then on that radio can originate a signed bulletin with no phone involved: a panic button by the door, or a beacon that reports a condition.

A device signs as a device. It is signal grade and never an approver, because a box is not a person and holding a radio is not the same as holding somebody's key. Anywhere the app shows who signed a record, a device-signed one says so.

A stolen radio is a stolen key. A phone key is protected by the phone. A radio's key is protected by the radio, which is a small object that lives outdoors and may have no PIN. Enroll a radio only if you are willing to stand behind whatever it signs, and revoke it the moment it goes missing. Revoking stops a bridge accepting anything new from it; it does not retract what was already passed along.

More than one bridge

Your phone among several bridges

A neighborhood may end up with more than one bridge. The app collects every bridge it can discover, prefers the one answering best, and moves to another when the current one goes quiet. An address you typed yourself always wins over one that was discovered.

Bridges linked to each other

Two bridges that can reach each other on a network share what they have heard, so the neighborhood next door joins without anyone re-entering anything. A linked bridge is untrusted by design: everything it hands over goes through the same signature check as anything else before it is stored, so a bad peer can waste a bridge's disk and can never put a false bulletin in front of a neighbor.

Neighbors link bridges the ordinary ways: a second Wi-Fi adapter in the Pi, a guest network on the house next door, or a pair of directional Wi-Fi units between two roofs.

Linking bridges adds coverage, not resilience. Wi-Fi runs on mains power, and mains power is the first thing an emergency takes. Linked bridges help on an ordinary day, and on the very common day when the internet is out but the lights are on. They are not a way to reach further in a blackout. Reaching further with no power and no network is what the radio is for.

Reaching Meshtastic radios

Meshtastic is the other widely used LoRa mesh, and the two firmwares cannot hear each other over the air even on the same frequency, because the packet formats differ. A bridge can carry Meshbell bulletins onto a Meshtastic radio anyway, over a link written from the published message format with none of the Meshtastic project's code, which is why nothing from it is in the app.

It runs on the bridge only and it is off until an operator turns it on. People running the stock Meshtastic app see nothing: Meshbell rides a private channel number their app does not display. It is a way to reach a neighbor who already carries a Meshtastic radio, not a way to talk to the Meshtastic network at large.

Architecture

The domain logic is pure and portable. It builds and tests on a Raspberry Pi with no Apple hardware in the loop, so the parts that decide whether a message is trustworthy are verified continuously rather than only at release. The iOS app is a thin renderer over it.

Honest limits

Stated plainly, because an emergency tool that oversells itself is dangerous.