Relayium

Receive files from the command line

Last updated: 2026-08-06

Sending is only half the story — sooner or later you're on the receiving end: a colleague wants to hand you a file across the internet, one of your own machines wants to hand off to another, or you want to reach out and grab something from a server you administer. The Relayium CLI covers all three with a different command for each, and none of them need an account.

Pick receive when someone else is pushing to you by pairing code, serve when you want a standing inbox that trusted machines can push to any time, and pull when you're the one reaching out to a server you can already ssh into.

Three ways to receive, and when each applies

Which command you run depends on who's starting the transfer and how the two machines know each other:

receive: someone sends you a file across networks

What you need before step 1

  • The CLI on this machine. relayium version prints a version string; a shell that answers command not found means it is not installed here yet.
  • A sender who is signed in and at their terminal right now. Only they need an account — you never sign in to receive.
  • The six digits, passed to you out of band. They live five minutes from the moment their CLI minted them, so agree on the moment first.
  • A way to read six more digits back to them afterwards: the SAS is compared out loud, not on screen.
  • The other end must be the CLI. A browser cannot join a CLI pairing code — if that is what you have, ask for a relayium up link instead.

This is the receiving half of relayium send. The other person runs relayium send <path> on their end (after relayium login); their CLI mints a 6-digit code, good for 5 minutes, and prints it. They tell you what it is over any channel you both trust — a call, a chat message. You run receive with that code:

relayium receive 483920

# or into a specific directory
relayium receive 483920 ./downloads
  1. Agree with the sender on when they will run send. The code starts expiring the moment it is minted, not the moment you get it.

  2. Take the six digits over a channel you both trust — a call, a chat window, the room you are both in.

  3. Run receive from the directory where the files should land, or name one explicitly.

    relayium receive 483920
    relayium receive 483920 ./downloads
  4. When both terminals print a verification code, read yours aloud and check it matches theirs. It is not the pairing code, and it is the only thing that rules out a substituted endpoint.

  5. Leave the terminal alone until it returns to the prompt. This is one live session: closing either end stops the transfer.

What a successful receive looks like

The connection is announced as direct, and both terminals print the SAME verification code. Different codes are the one result you must not accept — stop and check with the sender which machine they are on.

$ relayium receive 483920
verification code (SAS): 271044 — not the pairing code; compare it on both ends to rule out a substituted endpoint
path: direct

serve: turn this machine into a listening drop box

serve works the other way around: instead of you reaching out, other machines push straight to you over relayium:// — built for machines you already trust, like your own laptop pushing to a NAS, or a build server dropping artifacts on a box you own — over a pinned TLS 1.3 connection, no SSH, no rendezvous.

relayium serve

# a specific directory, port, and allowing delete requests
relayium serve --dir ~/incoming --port 9031 --allow-delete
  1. Start the listener, naming the directory pushes should land in.

    relayium serve --dir ~/incoming
  2. When a new machine pushes for the first time, serve shows its address and fingerprint and asks. Approve it once and later pushes from that fingerprint go through silently.

  3. If this listener will run without a terminal, do not rely on that prompt — nobody is there to answer it, and an unrecognised pusher is rejected outright. Pre-authorize instead, as the next section describes.

Pre-authorize for unattended serve

For a serve that runs unattended (systemd, a background script), have the pusher run relayium id to print its fingerprint, then approve it ahead of time from the receiving side:

relayium authorize <fingerprint>

pull: reach out and fetch from a server you can ssh into

pull is the mirror of push: instead of waiting for someone to send you something, you reach out over your existing SSH access and fetch files back.

relayium pull user@host:/path/to/files ./local-dest
  1. Confirm the remote actually has the CLI. pull runs relayium on the far end, and unlike push there is no tar fallback, so a missing binary fails the whole command.

    ssh user@host command -v relayium
  2. If it is missing, install it there first.

    curl -fsSL https://relayium.com/install.sh | sh
  3. Pull the files back over your existing SSH access. -i and -p behave like ssh's own.

    relayium pull user@host:/path/to/files ./local-dest

When it doesn't work

Five failures cover nearly every unsuccessful receive. Which command you were running decides which of them applies, and each has a line to read or a command to run that settles it.

Symptom, check, fix

You type the code and the rendezvous refuses it.
relayium receive 483920
# the rendezvous refuses the code

Almost always the five minutes elapsed — the code expires from the moment the sender's CLI minted it, not from when you were told. Ask them to run send again and read you the fresh digits straight away. A mistyped digit looks identical from here, so re-read it back before assuming it lapsed.

The transfer completes but you cannot find the files.
relayium receive 483920 ./downloads

With no destination, receive writes into the directory you ran it from, which is rarely where you were looking. Pass one explicitly, or run pwd first and be sure.

It fails with "no direct connection to the peer (both ends behind strict NAT?)".
relayium receive 483920
# no direct connection to the peer (both ends behind strict NAT?): …

The CLI pairing path is direct-only by design: when no direct route exists it fails rather than routing your file through a relay. Nothing on your side fixes that. Ask the sender for a relayium up download link instead, or, between machines you both control, use daemon-direct or push over SSH.

pull fails immediately, complaining that relayium was not found.
ssh user@host command -v relayium
# (no output)

pull runs relayium on the remote — it is the sender in that exchange — and there is no tar fallback the way push has one. Install the CLI on the remote first, then re-run the pull.

A machine pushes to your serve listener and is rejected without ever prompting you.
relayium serve --dir ~/incoming

The prompt only exists when serve has a terminal. Under systemd, in a script, or behind a pipe there is nobody to ask, so an unknown fingerprint is refused outright. Have the pusher run relayium id and pre-authorize it here with relayium authorize <fingerprint>, using the same --config-dir the listener runs under.

Frequently asked questions

Do I need an account to receive files?

No. All three ways — receive, serve, and pull — are completely free and need no Relayium account on your side. The one sign-in anywhere is the sender's in receive mode, so their CLI can mint the pairing code.

Does relayium receive interoperate with the browser's pairing code?

No. The CLI's pairing-code protocol is separate from the browser's join-link and QR flow at relayium.com — they use different handshakes and don't talk to each other today, so a CLI code only pairs with another CLI. That's on the roadmap, not something you can rely on yet. Until then, a browser recipient wants a relayium up link rather than a code.

What happens if an unknown machine pushes to my serve listener?

In a terminal, you're prompted to approve it by address and fingerprint on its first push, and the approval is remembered. Without a terminal — a systemd service, a cron job — there's no one to ask, so an unrecognized pusher is rejected; pre-authorize it first with relayium authorize <fingerprint>.

Can I pull from a server that doesn't have relayium installed?

No. pull always needs relayium on the remote end; there's no tar fallback the way there is for push. Install relayium there first.

Where does relayium keep my identity and trusted peers?

In ~/.config/relayium by default — override the location with --config-dir on any command that touches identity or trust.

Ready to receive your first transfer? Install the CLI and pick receive, serve, or pull.

Get the CLI

Keep reading