Skip to main content
floe send
Sends files and folders from your terminal to one receiver with Floe’s CLI, straight to their device and encrypted end to end.

The short version

Run floe send with your files or folders, then give the receiver the room code, three words such as olive-tiger-castle, or the link it prints. Whoever uses it first gets the files, so send it only to the person you mean. Keep the terminal open until the Sent box appears. To send through someone’s request link instead, add --to with their link: see Send through a request link.

Examples

Send a single file:
Terminal
Send multiple files at once:
Terminal
Send an entire folder (transferred recursively):
Terminal

Output

After reading your files, floe send shows a summary of what will be sent, then prints a sharing panel:
Output
That is floe 1.12 and later. floe 1.11.7 and earlier print a link with no link key, https://floe.one/#room=6f1c2b9e-4a5d-4c3b-9f7e-2d1a0b9c8e7f, and no line about quotes. Both lead to the same room, the meeting point on Floe’s server for this one transfer. Share one of them: See how long a code and a link last for what ends each one early. For a single file, the Sending line shows the file’s name in place of the count. In floe 1.12 and later the two are not equal. A receiver who opens the link in a browser, in floe receive 1.12 or later, or in Floe Desktop 1.1 or later checks that your side holds the link key. The code carries none, so choosing the code is choosing no check. Your own floe send only detects: it stops on a proof that is wrong and goes on when no proof comes. So a server that plays a receiver with no link key gets the whole file, and the Sent box still prints. --link-only closes that gap. See What the link key checks. floe send waits for the other side with no time limit, for as long as its own connection to Floe’s signaling server lasts. If that connection drops while it waits (the computer sleeps, the network changes, the server restarts), it ends with Error: the connection to the server was lost before the peer connected. Run it again and share the new code. floe 1.11.0 and earlier print Error: peer disconnected before connecting there. The code and the link are all that protect the transfer. Whoever enters the code or opens the link first gets the files, and floe send does not ask you to approve them, so share them only over a channel you trust. See Known limitations. If the server does not hand out a code, for example because it is limiting requests from your network, floe send prints a line that starts with Warning: could not generate short code: and gives the cause. The panel then shows the Link row alone and the send goes on: share the link. A share link with a link key holds an &, which a terminal reads as the end of a command, so a link passed to floe receive goes in quotes. What an unquoted one does: On floe.one the link is 93 columns wide with its indent, so an 80-column terminal wraps it. A line break that gets into a copy reads as an incomplete link in floe 1.12 and later, with the This link looks incomplete line, and the link key is not printed. A space that gets into an unquoted copy reaches floe as a second word, and it prints Error: accepts 1 arg(s), received 2. Copy the link again, whole. Once the receiver connects, Floe sets up the connection and sends the files in the order you listed them, each with a live progress bar:
Output
The Connected line says which way the files travel: (direct) when the two devices reach each other, (relay) when they go through the relay, a server that passes the encrypted data along. It is read once, as the connection comes up. On the rare occasion the route cannot be read, the line is Connected alone and the transfer goes ahead. On a relayed route, more than 2 GB of files stops the send before any file data moves, with a line such as Error: transfer blocked: relay connections are capped at 2 GB (selected 3.1 GB). See File size limits. While a file is still in flight, its line also shows the time so far and the time left, for example [1/3] report.pdf 85% [██████████░░░░░] (1.4 MB/s) [6s:1s]. Those brackets disappear once the line reaches 100%. The bar stretches to the width of your terminal, and names longer than 30 characters are cut short. The speed on the bar counts 1 MB as 1,000,000 bytes (kB, MB), while the box below counts 1 MB as 1,048,576 bytes, so the two can differ slightly. The Verified SHA-256 matched row is the receiver’s report that every file matched the SHA-256, a fingerprint of the file’s contents, that your floe sent with it. It is not a check made on your side, and it says nothing about who the receiver is. It appears when the receiver is floe receive 1.11.0 or later, Floe Desktop 0.3.0 or later, or a browser, and every file matched. Otherwise the box holds the Sent and Time rows alone. See File checks. Time counts from the moment the receiver accepted, so the time they took to answer is in neither the time nor the average speed. In floe 1.11.0 and earlier it counted from the moment the connection came up. When the receiver runs a different Floe release from yours, one extra line names it as the transfer starts, for example Peer version: desktop-v1.1.0. A browser sends no version, so the line never appears for one. Versions do not need to match.

What the other person sees

What the receiver sees depends on what they receive with:
  • floe receive shows how many files are coming and their total size, or the name and size of a single file, then asks Accept? [Y/n]. Nothing is saved until they answer. See Confirmation prompt.
  • Floe Desktop starts saving at once: a code or a link has no accept step there. See Receiving files.
  • A browser shows each file as it arrives, each with its own download button. See Receive files in your browser.
They see each file’s name, and for a folder, where each file sits inside it. On a direct connection their device also learns your IP address. --relay-only hides it, at the cost of the 2 GB cap: see CLI flags reference.

Send a folder

When you send a folder, Floe walks it and everything inside it and rebuilds the same relative paths in the receiver’s output folder. Every file is included, hidden files and dotfiles among them, so a folder holding .git or .env sends those too. Empty folders are not recreated on the other side, because Floe sends files and an empty folder has none.
Terminal
A trailing slash changes this. Floe names each file relative to the folder’s parent, and a trailing slash makes the folder itself the parent, so the folder’s name drops out and its contents land directly in the receiver’s output folder:
Terminal
The same applies to a trailing backslash on Windows. Shell tab-completion often adds one, so drop it if you want the folder’s name kept. floe send . works the same way: it sends what is in the current folder, without that folder’s name. A file you name directly arrives under its own name only: floe send a/b/report.pdf arrives as report.pdf. Two files with the same name from different folders arrive on floe receive and Floe Desktop as notes.txt and notes (1).txt. A link inside a folder (a symlink, or a junction on Windows) that points to a file is sent with that file’s contents and size. A link to a folder, or one that points nowhere, stops the send before it connects, because Floe does not follow links to folders. A path you give that is itself a link to a folder is sent as that folder, under the name you typed. floe 1.11.0 and earlier sized a linked file by the link itself, which could stop the transfer partway. Floe sends only regular files and folders. A pipe, a socket or a device that you name directly stops the send before it connects, with Error: cannot send <path>: it is a pipe, a socket or a device, not a file. Inside a folder, such entries, and links that point to them, are left out of the transfer without a message. floe 1.11.7 and earlier send a pipe or a device that you name directly as an empty file, and a socket or a pipe inside a folder stops or hangs the send. The receiver checks where each file would go before saving it. It refuses a file nested more than 32 levels deep, a path too long for it to save, or a file too large for its drive. floe receive 1.11.0 or later and Floe Desktop 0.3.0 or later make these checks. floe send then stops with one line, such as Error: A file name or folder path is too long for their computer. Shorten it or zip it first., and exits with status 1. Files the recipient saved before that one stay there. See Paths that are too deep or too long. A browser recipient refuses one thing of this kind: a file whose description is longer than 1,000 bytes, which takes a relative path of about 800 bytes. floe send stops with the same line. A web app that someone hosts themselves can run an older version, which does not answer in that case: see What an older web app shows.

When a send ends

A send that worked exits with status 0 after the Sent box. To floe receive 1.11.0 or later, Floe Desktop 0.3.0 or later, or a browser, the box prints only after the receiver has said it holds every file. To an older receiver, it prints once the other side’s connection has acknowledged all the data. See File checks. floe send never reports to the public transfer counter. Only a receiver does, and it can opt out: see Opting out of the global counter.

Stop a send with Ctrl+C

Press Ctrl+C at any time to stop. floe send prints Canceled. and exits with status 130. On macOS and Linux, a hangup does the same: closing the terminal, losing the SSH session, or SIGHUP, unless you started floe with nohup. floe 1.11.7 and earlier stop at once on a hangup and tell the receiver nothing. Once the two devices are connected, floe send first tells the receiver that the sender stopped and closes the connection, which takes about a second at most. What the other side sees depends on how far it had got: In the middle of a file on a slow link, the notice may not get out in time. The receiver then sees a closed connection instead, such as connection closed mid-transfer in floe receive. In floe 1.11.0 and earlier, Ctrl+C told the receiver nothing, so floe receive and Floe Desktop waited 60 seconds and reported a stalled transfer, and a browser waited until its connection failed.

When the other side stops it

floe send prints one line and exits with status 1: A receiver that cannot keep a file says why, and floe send prints Floe’s own sentence for the reason: A line after Error: that starts with receiver is a reason the receiving app gave in its own words, for a case Floe has no sentence for, such as Error: receiver rejected the file description: and a detail. It is shown as it came, cut to 300 characters. Read it as the other side’s words, not as advice from Floe.

When something on your side stops it

These end the send with status 1: When the receiver is told that a file could not be read, floe receive prints Error: The sender stopped: a file could not be read on their device. Ask them to check it and send again., and Floe Desktop and a browser show the same sentence. On a slow link the notice may not get out in time, and the receiver sees a closed connection instead. Through a request link, their Floe Desktop shows only “The sender stopped this drop”, or, before they accept, goes back to waiting with no line. floe 1.11.7 and earlier close the connection without telling the receiver.
floe send --link-only
Needs: floe 1.12 or later. An older floe stops with Error: unknown flag: --link-only. --link-only makes no code, so the panel has a Link row alone. It names no file until the receiver has proved it holds the link’s link key, so a server in the middle learns no file’s name, size or bytes. It has no environment variable: it is a choice about one transfer. It proves nothing about who the receiver is: anyone holding the whole link can pass. See What the link key cannot see. The receiver needs the whole link, in a browser on floe.one or on a web app image of 1.12.0 or later, in floe receive 1.12 or later, or in Floe Desktop 1.1 or later. Anything else has no proof to give. Neither line has Error: in front, and both end the send with status 1. A receiver too old to prove the link is told to update. floe receive from 1.10.8 to 1.11.7 prints Cannot transfer: your floe is too old for this peer. and Run `floe update` to upgrade. One older than that prints connection closed before any file arrived (the sender canceled, or the transfer was blocked). --link-only and --to cannot be used together, and floe stops before any network call with Error: if any flags in the group [to link-only] are set none of the others can be; [link-only to] were all set.
floe send --to
Needs: floe 1.11.0 or later, and a request link from someone whose Floe Desktop is open. A link from Floe Desktop 1.1 or later holds a link key and needs floe 1.12 or later: floe 1.11.7 stops on it with the This link looks incomplete line below. A floe older than 1.11.0 stops with Error: unknown flag: --to, and floe update fixes both. See Install the CLI. Someone who uses Floe Desktop can make a request link so that one person can send files straight to their PC. If you were sent one, you can open it in a browser (see Sending through a request link), or give it to floe send with --to and send from your terminal. Floe registers no code and prints no link: the files go only to the computer that made the link.
Terminal
Put the whole link in quotes, including everything after the #: the room id there reaches their computer, and the link key checks it. A link with nothing after the # stops at once, before Floe contacts any server, with:
Output
A link cut before its link key gets as far as their computer, which refuses it, and ends on the same line.
The whole link, room id and link key included, is on your command line. Your shell keeps it in its history, and while the command runs, other users of the same computer can see it in the list of running processes. Anyone with the whole link can send through it while it is open.
Floe checks your files, connects to their computer, and asks them to accept:
Output
On a link with a link key, in floe 1.12 and later, the Waiting line appears only once their computer has proved it holds the link key. floe waits up to 15 seconds for that, and names no file until then. A link from Floe Desktop 1.0.x holds no link key, so it has no such check and no such wait. See What the link key checks. Their Floe Desktop shows the request: how many files and their total size, and the folder they will go into. Nothing is written to their computer until they click Accept, unless they made the link with Auto-accept on, which saves an ordinary drop without asking. They have 9 minutes 45 seconds to answer, which the line rounds down to whole minutes. Their computer sees your IP address unless you add --relay-only. Once they accept, each file streams with the same progress bar as any send, and the command ends when their Floe confirms that every file arrived:
Output
For a single file the first line reads like 1 file arrived (48 Bytes in 0s, direct)., and the route is left out when it could not be read. The time counts from their Accept. The second line appears only when their Floe checked every file against the SHA-256 your floe sent with it, and every one matched. It is their report, not a check made on your side. The Sent box of a plain send is not printed. When their Floe is a different version from yours, a Peer version: line names it as they accept, for example Peer version: desktop-v1.1.0. Through a request link the line appears only for a version shaped like a Floe release (three numbers, with an optional v or desktop-v in front) or dev. Any other text prints no line, so the other side cannot put words of its own on your terminal. floe send --to exits with status 0 only after their Floe confirms that every file arrived. Ctrl+C, SIGTERM and, on macOS and Linux, a hangup exit with status 130, and every other outcome prints its fixed lines, listed under Messages, and exits with status 1. Each outcome is one of those lines, never the other side’s own words. A link made on floe.one works only with floe.one’s own server, https://api.floe.one, which is the default: leave --server out and unset FLOE_SERVER, or pass --server https://api.floe.one. A link made on a self-hosted server needs that server named. When the link and the server do not match, the send stops before Floe contacts any server, with Couldn't connect to their computer. Nothing was sent. See Use a self-hosted server. Floe never prints a request link back. A request link given where a file or folder goes, with --to left out, or typed as the command itself (floe <link>, or floe help <link>), is refused before Floe contacts any server. floe prints this one line, with no Error: in front, and exits with status 1:
Output
A link and a path swapped, with the file after --to, stops on the This link looks incomplete line above. So does --to with nothing after it, such as --to "$LINK" with LINK unset. Neither case prints the usual cannot read error, which would repeat the link, with its room id and its link key. Ctrl+C stops the send and exits with status 130. On macOS and Linux, a hangup (a closed terminal, a lost SSH session, or SIGHUP) does the same unless floe runs under nohup. floe 1.11.7 and earlier stop at once on a hangup. Otherwise either prints one line:
  • before they accept: Canceled. Nothing was sent.
  • after they accept: You stopped this drop. and how many files were saved, such as You stopped this drop. 4 of 12 files were saved.
With nothing saved after they accept, floe 1.12 and later print You stopped this drop. alone, because part of a file may have gone. floe 1.11.7 and earlier print You stopped this drop. Nothing was sent. there. Once connected, their computer is told that you stopped, and the files that arrived stay there. If their Floe confirms the last file while floe send is stopping, the drop still counts as delivered: the arrived lines print and the status is 0. A Ctrl+C after the outcome is decided prints nothing and changes nothing. A second Ctrl+C exits with status 130 at once.

Messages

Each of these ends the command with status 1. “This link has already been used” also covers three more cases:
  • the person who made the link declined a request and has not reopened it;
  • they closed the link while a request was waiting for their answer, or after a decline;
  • senders have joined the link more than 6 times in 1 minute. If you had just run the command several times in a row, wait 1 minute and run it again first.
If their computer disappears while you wait or send (it crashes, or its network goes), the command ends about 30 seconds after the last word from it, on one of the two Connection lost. lines. When their Floe stops the drop, floe send --to prints one of these, then how many files were saved, such as 4 of 12 files were saved. (1 of 1 file was saved. for a single file) or Nothing was sent. In floe 1.12 and later, once they have accepted, part of a file may have gone, so with nothing saved there is no such line. A decline or a missed answer that comes after they accepted then reads The drop stopped on their computer. A few outcomes print the same Error: line as a plain send, described under When something on your side stops it:
  • a path that cannot be read, and a folder with no files in it (Error: no files to send);
  • a file that changed while it was being sent;
  • --relay-only against a server with no relay;
  • a relayed connection with more than 2 GB selected, which stops before anything is sent with Error: transfer blocked: relay connections are capped at 2 GB (selected 38 GB).

Flags

See CLI flags reference for --server, --no-relay, --relay-only, --web, and --iface, and for --to and --link-only, the two flags of floe send itself. To run floe send from a script or a CI job, see In scripts and CI.
Last modified on November 5, 2026