Skip to content
New: send files with no internet at all. Try offline mode

Developers

Command line and API

The command line tool speaks the same encrypted protocol as the browser, so a terminal can send to a phone and a browser can send to a server.

Send from the terminal

npx ferry-send send report.pdf photos/

The tool prints a QR code, a link and a 6-digit code. Open any of them on the other device. Folders are sent with their structure. The command exits when every file has arrived.

Receive in the terminal

npx ferry-send receive 482107
npx ferry-send receive "https://ferry.sholajegede.com/room/…#k=…" --out ~/Downloads

When you join with a 6-digit code, the terminal shows a security code. The sender confirms the same code on their screen before the transfer starts.

Options

HTTP API

The API creates and inspects transfers. File data never passes through it. Devices still connect to each other directly and encrypt everything they send.

Create a transfer

POST https://ferry.sholajegede.com/v1/rooms
Content-Type: application/json

{
  "roomId": "<16 random bytes, base64url>",
  "joinTokenHash": "<sha-256 hex of your join token>",
  "name": "Build server"
}

The response has what a client needs to host the transfer:

{
  "roomId": "p1Qm…",
  "code": "482107",
  "expiresAt": 1791547200000,
  "deviceId": "…",
  "deviceSecret": "…"
}

Create the link secret yourself: 32 random bytes in base64url. Derive the join token from it with HKDF-SHA-256, using 32 zero bytes as the salt and ferry/join/<roomId> as the info string, and send the SHA-256 of the base64url token. The link to share is https://ferry.sholajegede.com/room/<roomId>#k=<link secret>. The secret stays in the part after the # sign, which is never sent to a server.

Check a transfer

GET https://ferry.sholajegede.com/v1/rooms/<roomId>

{ "roomId": "p1Qm…", "status": "open", "expiresAt": 1791547200000, "devices": 2 }

How the encryption works