Scan to connect
Open this page on your computer, then scan the QR code with your phone.
Creating session…
The encryption key is embedded in the QR code and never sent to the server.
API Reference
How it works
- Session creation — Initiator calls
POST /api/qr/session. - QR display — Browser generates a QR code encoding the session URL and a 128-bit AES key (in the URL fragment, never sent to the server).
- Scan & connect — Joiner scans QR, extracts key from fragment, opens WebSocket.
- AES handshake — Both peers exchange encrypted challenge/response to verify the shared key.
- WebRTC attempt — Peers try to open a direct
RTCDataChannelvia SDP/ICE signaling through the WebSocket. If it fails, the WebSocket relay is used. - File offer — Sender transmits metadata:
{ name, size, type, sha256 }. - Accept / reject — Recipient confirms or declines.
- Chunked transfer — File sent in AES-GCM encrypted chunks over the direct data channel (if available) or the relay.
- Checksum validation — Recipient verifies SHA-256 against the pre-announced hash.
- Ready for next — Both sides return to idle, ready for another transfer.
Endpoints
POST /api/qr/session
Create a new transfer session. Returns { sessionId }.
GET /api/qr/rtc-config
Return { iceServers } for the WebRTC peer connection. Configured by STUN_URLS.
WS /api/qr/ws/:sessionId?role=initiator|joiner
WebSocket relay. Binary frames carry encrypted file chunks; text frames carry JSON control messages and WebRTC signaling (offer/answer/ICE).