The short version
Most people meet three of these. Anyone who has your link or room code can receive your files, so send it only to the person it is for. On a direct connection the other person’s device learns your IP address, unless you turn on Hide my IP. A browser that receives can hold only so much, so receive very large transfers with Floe Desktop or the CLI, or in smaller batches on a phone. Floe’s server also introduces the two devices, and a link key checks that introduction on a link that carries one. The check has limits, and the next four sections say exactly where they are.Security and privacy
What the link key checks
Floe’s signaling server passes along the short IDs the two devices use to agree on encryption keys. It cannot read your files and never sees one. But a server that wanted to could swap in IDs of its own, sit between the two peers, and decrypt everything. A link key is Floe’s check for that. A link from the web app, fromfloe 1.12 and later, or from
Floe Desktop 1.1 and later carries one after the #: 128 random bits that no server receives. Once
the two devices connect, each side that holds the link key proves it, with a proof tied to the
certificates actually in use on that connection. A server that swapped the IDs does not hold the
link key, and a proof made on one connection does not pass on another, so it cannot make a proof
that passes. Encryption explains the
IDs, and Transfer protocol has the exact proof.
What each app does with the link key decides how far that goes:
So a request link from Floe Desktop 1.1 and later is checked both ways, and one from Floe Desktop
1.0.x is checked neither way, because it holds no link key.
A sender that only detects can lose the whole file. It cannot tell a server playing a receiver
from a real receiver with no link key, such as someone who typed the room code, so it goes on. That
server gets every byte, not only the file’s name and size. Its words can reach the sender’s screen.
Its word that it received the files earns the sender’s
Verified row or green check mark, and that
is only that side’s word.
The receiver is the one who notices. A receiving page that holds the link key stops after 30
seconds if the other side connects and says nothing, and says it could not confirm who sent the
link. So a server that takes the file from the sender and keeps quiet is caught by the receiver,
not by the sender, whose page says the files were sent. floe receive 1.12 and later and Receive
in Floe Desktop 1.1 and later stop after the same 30 seconds, on their usual lines for a sender that
never starts: connected, but no data arrived from the sender within 30s and “The sender never
started sending”. A server that never connects the receiver at all leaves nothing to check, and the
transfer just never starts.
What you can do: when it matters, share the link and not the code, and ask your receiver to open
it in a browser, floe receive 1.12 or later, or Floe Desktop 1.1 or later. With floe 1.12 or
later, send with --link-only. Ask your receiver whether the files arrived,
and if they read that the sender could not be confirmed, assume someone else has the files.
A room code or a link with no link key has no check
A room code carries no link key, so a transfer joined by code has no check.floe send and Send in Floe Desktop print the code beside the link, so the person who chooses
the code is choosing no check. The server also chooses the code’s text and the room a code resolves
to.
A link with no link key has no check either, and nothing on screen tells a checked link from an
unchecked one. That covers a request link from Floe Desktop 1.0.x and every older share link.
What you can do: give the link rather than the code when the check matters, and share from the
web app, floe 1.12 or later, or Floe Desktop 1.1 or later, so that the link holds a link key.
What the link key cannot see
The proof says “holds the link”, not who. So the check cannot see:- Whoever serves the web app’s JavaScript. It holds every link key its pages open. On floe.one that is Vercel and the build, which the same operator publishes. On your own instance it is your web image and the edge in front of it. It is also anything else on the page, such as browser extensions and in-app browsers, and the docs host, which serves script on the same origin.
- An edge that can rewrite the page. For browser peers, a one-domain edge or a proxy that inspects TLS can change the page as well as pass the signaling along.
- A stored copy of the page’s code. A script on the same origin can plant an entry in the site’s stored copies. An answer from the network overwrites it, but the stored copy runs when the request for that file fails. See In the browser.
- Anyone who held the whole link. Everything that held it can pass the check: chat and mail
services, link scanners, browser history and its sync, clipboard history, and a photo of the QR
code. So can a shell’s history, and the process list while
floe receive "<link>"runs, which is how the line under the box infloe send1.12 and later says to pass it. A server plus any of those goes unnoticed.
api.floe.one you are trusting the same operator who publishes the client, which is the ordinary
situation for any hosted service.
There is no verification code to compare
A short verification code is the older defense against a server in the middle. It is worked out from both devices’ keys, and the two people read it to each other over a channel an attacker does not control, such as a phone call. If the codes match, nobody is in the middle. No client computes or displays that code today, in the web app, Floe Desktop or the CLI. A link key checks for a server in the middle with nobody reading anything, but only as far as What the link key checks says: a sender may only detect, and it shows who holds the link, not who they are. A transfer joined by room code, or by a link with no link key, has neither. What you can do: use a link that carries a link key, or encrypt the file yourself before you send it.Anyone with the link or code can receive
A share link or a room code is the only thing that protects a transfer. Floe has no accounts and no password step. Whoever opens the link or enters the code first, while the sender is still waiting, takes the receiving seat and gets the files. The sending app does not ask the sender to approve them. A room code is three words from a list of 1,247, so it can be guessed. The server allows each network address 10 wrong codes a minute, and a self-hosted server can set its own number. A code stops working when a receiver joins, when the sender leaves, or after 10 minutes: see How long a code and a link last. A link carries a long random room id instead of words, which is far harder to guess, and it works for as long as its sender is still waiting. A link key does not change this: whoever holds the whole link holds the link key too, and passes the check. Once a sender and a receiver on two different networks have started connecting, a device on a third network is turned away for as long as the room exists. So a link that leaks later cannot be used from somewhere else to take the receiver’s place. Devices that share one network address count as one, so a sender and a receiver on the same network are not covered. See A room holds exactly two people. The link is only as private as the channel you send it through: a mail security service that rewrites links may see all of it. See The room secret stays out of every server log. What you can do: send a link or a code only over a channel you trust, to the one person it is for. If either may have reached someone else before your receiver joined, stop the send and start a new one, which gets a new link and a new code.The other person learns your IP address
A direct connection is two devices talking to each other, which means each one knows where the other is. That is not a leak; it is how any peer-to-peer connection works, and a video call does the same thing. With a request link, that happens as soon as the sender starts the send and the two devices connect, before the person who made the link accepts or declines. Declining does not take it back. What you can do: Floe Desktop has a Hide my IP address switch that forces every transfer through the relay, so the other side sees the relay’s IP address instead of yours. The CLI’s--relay-only flag does the
same. The web app’s Send page has no equivalent, but the page a sender opens from a request link
has its own Hide my IP checkbox. The trade is speed and the 2 GB
session cap.
The relay sees more than the signaling server does
When a direct path is impossible, traffic goes through a TURN relay. The relay cannot read anything: the data is encrypted before it arrives and decrypted only on the recipient’s device. But the relay is an endpoint that both devices connect to, so it observes both IP addresses and the timing and size of what it forwards. Onfloe.one that relay is Cloudflare’s Realtime TURN
network, which is infrastructure Floe does not own, and its operator may log those facts about the
transfer for its own security purposes. Cloudflare also sees each device’s IP address while a connection is
being set up, on every transfer: see What the relay can see.
What you can do: stay on a direct connection where you can, or self-host with
your own coturn relay.
The public counter is a vanity metric
The total on the homepage is fed by receivers reporting a byte count after a transfer. It is protected by a per-address rate limit and a per-report size cap, and nothing else. Anyone can post a plausible number to it. It is an honest best-effort figure, not an audited one, and it is deliberately built that way: adding real integrity would mean identifying the reporter, which is exactly what the counter avoids. It carries no file names, no per-transfer records, and no link to anyone. See Aggregate statistics.Sending and receiving
A browser receiver is limited by what the browser can hold
The web app keeps every file it receives inside the browser until you leave the page, so that you can still save it. What counts is therefore the size of the whole transfer, not of its largest file, and how much fits depends on the browser.- Chrome, Edge, and other browsers built on Chromium, Chrome’s engine, in a normal window: the tab holds no more than about 16 MB of a file at a time. The browser keeps some of what has arrived in memory, about 2 GB on a computer. It moves the rest into temporary files of its own on disk, up to a limit it sets from the size of the disk, and less when the disk is nearly full. Past that limit the transfer stops and says the browser ran out of room.
- A private or Incognito window in those browsers: nothing goes to disk, so everything received in private windows shares the memory part alone, about 2 GB on a computer and much less on a phone. Past that the transfer stops the same way, and a normal window gets further.
- Firefox, Safari, and every browser on iPhone and iPad: every file is held in memory. A large enough transfer runs the tab out of memory, and on a phone that ceiling arrives sooner than you would like. The transfer stops and says the browser ran out of memory.
- Send several large files as separate transfers, a few at a time. The receiver saves each batch, then opens the next link, which starts the page empty.
- A single file too large for the phone has to go to a computer instead, through Floe Desktop or the CLI. Copy it to the phone from there with a cable or the phone’s own file app. Or make it smaller first, for example by exporting the video at a lower quality.
- Put both devices on the same Wi-Fi network. The connection is then usually direct, so the 2 GB relay cap does not apply.
A transfer that stops cannot be resumed
Floe has no resume. A transfer can stop partway because a connection dropped or one side closed its app. The files that had finished are then kept, and everything else has to be sent again in a new transfer, including the file that was moving. What is kept depends on the receiver. Floe Desktop andfloe receive leave the finished files in
the save folder and discard the file that was arriving: see
If a transfer stops partway. The web app keeps
the finished files in its list until you leave the page, so save them before you reload.
What you can do: keep both devices awake and online until the transfer ends. After a stop, ask
which files arrived and send only the rest.
A device that sleeps ends the transfer
Closing a laptop’s lid usually puts it to sleep, and a sleeping device ends the transfer as surely as closing the app. The browser page asks to keep the screen on, and Floe Desktop asks Windows to stay awake, but closing the lid or choosing Sleep still wins. What each side of a browser transfer sees once the sleeping device wakes:
Floe Desktop usually reads “The connection dropped before the transfer finished” on either side.
Do not count on the old link: after a sleep it can stop working without a message on the sender’s
page. Start a new transfer instead:
1
Save what arrived
The receiver saves every file that arrived. In a browser, do it before leaving the page.
2
Send the rest in a new transfer
The sender reloads the page, adds only the files that did not arrive, and shares the new link.
In Floe Desktop or the CLI, send those files again.
3
Keep both devices awake
Keep both devices awake and online until it ends. On a laptop, keep the lid open and plug it in.
There are no accounts
Floe has no accounts and no sign-in, so three things do not exist:- a list of what you sent that follows you between devices
- a way to take a file back once it has arrived
- a way to watch or stop a transfer from another device
Saving received files
The SHA-256 check covers the transfer, not your disk afterward
Floe checks every file it receives against the size the sender announced and, when the sender provides one, against the sender’s SHA-256 of the file. It deletes a file that fails either. File checks has the whole account. Two things the check does not do:- It covers the file as it arrived, so it cannot notice damage that happens on your disk
afterward. Floe Desktop and
floe receivetake the SHA-256 while they write the file and never read it back. The web app checks the copy it holds, before your browser saves it. - A file that comes without a SHA-256, or whose check did not finish
in the time allowed, is checked
against its size and nothing more. That file is kept, and the transfer finishes without the
green check mark or the
Verifiedrow. See When there is no mark.
sha256sum on Linux,
shasum -a 256 on macOS, Get-FileHash on Windows.
Windows cannot keep two names that differ only by a reserved character
Windows refuses< > : " | ? * in a file name, so Floe Desktop and floe receive on Windows
replace each of them with _ before writing. A name that starts like a drive, such as
P:L 2025.xlsx, loses its first two characters instead and is saved as L 2025.xlsx: see
Names Windows cannot represent are adjusted.
Names that were distinct on the sending machine can then land on the same name. A Linux folder
holding report:v1.pdf and report?v1.pdf arrives as report_v1.pdf and report_v1 (1).pdf,
and nothing on disk says which was which. The numbered suffix follows the order the files arrived
in, which is the order they were sent.
Nothing is overwritten and nothing is lost. The receiver never replaces an existing file, so
the second one is saved beside the first rather than on top of it. floe receive on macOS and
Linux keeps both names as they were sent, because those characters are legal there. The web app
replaces the same characters on every operating system, because a ZIP it builds may be opened on
Windows.
What you can do: if the distinction matters, rename the files before sending, or send to
floe receive on macOS or Linux. The progress line of floe receive and the History in Floe
Desktop both show the name that was actually written, so you can always tell what landed where.
Very deep or very long paths are refused
Before they write a file, Floe Desktop andfloe receive refuse one whose path inside the
transfer is too deep or too long, or that starts at a drive or a root. The receive stops there and
tells the sender why. Files saved before it are kept, and no setting or flag turns the limits off.
The numbers are in Limits.
What you can do: zip deeply nested folders before sending them. See
what the desktop app shows and
what floe receive prints.
Floe does not scan received files
Floe does not scan received files for malware. On Windows, Floe Desktop andfloe receive mark
each file as downloaded, the way a browser does, so SmartScreen and
Office’s Protected View, which opens a downloaded document read-only, treat it like any download. The mark needs a drive that can keep it, and not
every drive does. See
Received files are marked as downloads.
What you can do: open files you did not expect with the same care as any download, and save
to an NTFS drive, the format of a Windows PC’s own drive, when the mark matters. A drop through a
request link also renames file types that File Explorer opens by itself, such as shortcuts; see
Renamed files.
Request links and Floe Desktop
A request link works only while your PC is on
A request link is a live transfer, not a mailbox. Files move only while Floe Desktop is open on your PC and the PC is awake and online, and only while the sender’s page, or theirfloe send --to,
stays open. There is no resume: if the connection drops, the file that was moving starts over
through a new link. A drop that runs for hours can also be cut short by Windows restarting for
updates outside your active hours.
What you can do: keep the PC plugged in and awake for a long drop, and set Windows Update’s
active hours to cover it. A sender in a browser keeps the tab in front, and pins it for a long
drop. See Request links.
A hostile server can close a request link
Floe Desktop 1.1 and later closes a request link once 5 senders on it have failed the link key check, and the next sender reads that the link has ended. So a hostile server can end your link by seating 5 failing senders. That costs you the link and nothing else, and it is denial of service such a server already had: it could refuse to introduce anyone. The 5 is not a rate limit. A sender that says nothing or leaves does not count toward it, so a server can also keep your Floe connecting for as long as the link lasts without ever reaching it. The limits on how often senders can connect are under Limits. What you can do: make another link. If it keeps happening on one server, it is worth asking who runs that server.Windows decides where a notification appears
Floe Desktop sends standard Windows notifications, and Windows decides how they show: on which screen, in which corner, for how long, and whether Focus or Do Not Disturb hides them. Floe cannot pick a screen or a corner. A notification also stays in Notification Center after the request it announced has ended, or after you have answered it, until you clear it. Clicking a notification does not take you to the request: switch to Floe to answer it. What you can do: change how they show in Windows. In Floe’s Settings, click Open under Windows notification settings, then find Floe in the list (Floe Desktop for the Microsoft Store build). Turn notifications off there, or in Floe, if you would rather not have them. A request still flashes the taskbar button, the window title reads(1) Floe, and a notice appears inside Floe. See
With notifications off.