An invite is a signed contact card: your public key, your name, optional email and phone, and a greeting. It is how two people exchange keys without a directory server.
card := "WHCD" ‖ 0x01 ‖ string(public key, SSH wire format) ‖ string(name) ‖ string(email)
‖ string(phone) ‖ string(greeting) ‖ uint32(flags) ‖ uint64(time_ms) ‖ string(SSH signature)
flags: bit 0 = reply to an invite (sent by older versions, which offered an invite back)
The card is signed by its own key over "whisper/v1/card" followed by all
preceding bytes. Cards aren’t encrypted: they only hold what you chose to
share. An ed25519 invite link is about 360 characters.
What the signature proves — and what it can’t
The signature proves the sender holds the private key and that nothing in the card changed in transit. It cannot prove who the sender is: someone able to intercept the email or text could substitute a card of their own.
That’s what the safety code is for: 16 characters of Crockford base32
from the key’s SHA-256 fingerprint, e.g. 7C6T-9AFK-SPDS-CYVZ. Both the
inviter and the invitee see it and can compare it on a call or in person.
Showing the invite as a QR code in person avoids the problem entirely.


One invite, both directions
Accepting an invite adds the inviter and opens Write addressed to them, with a first message drafted. No invite back is needed: every message carries the sender’s public key and (optionally) name, so the inviter can add the sender with one tap on Reply. Until that first message is sent, Whisper keeps reminding the invitee — the inviter can’t write to them yet.
Ways to deliver an invite
- Link by text, email or share sheet:
https://crochik.github.io/whisper/i#… - QR code for a phone camera, in person
- Contact card: a vCard 3.0 (
.vcf) with the invite asURL;TYPE=Whisper:https://crochik.github.io/whisper/i#…, which can be saved in any address book