Invites
Invites are how people connect on Peers: adding a contact, inviting someone into a group, or joining a group from a link. One model covers all of them so that every flow works the same way and none of them require both people to be online at once.
Adding one of your own devices is different — it transfers your account secret — and uses device pairing instead.
The invite token
An invite is a small signed token. It carries the inviter's public identity, what it grants (a contact connection, or membership in a specific group with a role), how it can be used (once or many times, until an expiry), and the inviter's signature. The token is encoded once and can be shown as a QR code, a link, or plain text:
| Form | Example | Use |
|---|---|---|
| Link | https://peers.app/i#eyJ… | Messaging apps, email, QR codes |
| Deep link | peers://i#eyJ… | Opens the installed desktop app directly |
| Code | eyJ… | Paste anywhere; devices without a camera |
The token lives after the # in the link. Browsers never send URL fragments to
the server, so the peers.app web page that hosts the link can display and
hand it to the app without ever seeing it.
Because the token is signed, whoever accepts it can verify who issued it before doing anything. Because it names the grant, it cannot be used for anything else: a contact invite cannot join a group, and a group invite cannot grant a higher role than it states.
Invite modes
Contact invites connect two people. A one-off invite is used once and expires after seven days by default. Your profile QR (Identity → People → Share my profile) is a long-lived, reusable variant that produces contact requests you confirm individually.
Group invites have a role and a mode:
- Direct — the inviter picks an existing contact. The contact sees a ready-to-accept invite; no link changes hands. This is the simplest path once two people are connected.
- Link, approve each join — anyone with the link can request to join. The inviter approves or denies each request. Default lifetime seven days.
- Link, anyone joins — anyone with the link is admitted automatically as long as the link is valid. Default lifetime one day, maximum 30 days. Use it for a quick "everyone in this room" moment and let it expire. The join screen may briefly show Finishing your automatic join while the request and membership packet travel; no person needs to approve it.
Only Admin or Owner members can issue group invites, and a link cannot grant a role above the issuer's own.
Pending invites
Every invite you issue or receive is a row in your personal Invites table,
synced across your devices. Identity → Activity is the one inbox:
- Needs your attention — contact requests, direct group invites, join approvals, and other rows with a decision you can make now.
- Waiting on others — invites you sent and requests that are not yours to decide yet. Unsupported future device admissions stay here until actions exist.
- History — accepted, declined, expired, and revoked rows.
Section badges count only rows that need your attention. Resource screens link
into Activity when relevant rows exist, but do not keep their own history. The
CLI shows the same rows with peers invites.
#invites opens Activity. #invites/accept and #identity/activity/accept
open the shared paste-and-scan screen. Older #contacts, #groups, and
#devices links open the matching Identity section.
Rows are pending until resolved, then accepted, declined, expired,
or revoked. Pending rows expire with their token (inbound requests
after 30 days) and resolved rows are purged after 30 days.
Actions on a row:
| Row | Actions |
|---|---|
| Inbound direct group invite or contact request | Accept · Decline |
| Inbound join request for my link | Approve (optionally with a different role) · Deny |
| My outstanding invite | Revoke |
Regenerate on Identity → People → Share my profile revokes every token you have issued by bumping an invite epoch that all your tokens carry.
Delivery
Accepting an invite sends a reply to the inviter. Peers tries, in order:
- a direct connection to any of the inviter's devices;
- the Peers mesh, addressed to the inviter's user so any of their devices or a shared group peer can forward it;
- the Peers mailbox on
peers.app; - otherwise the reply is kept locally as
queuedand retried when connections change and every five minutes.
Both halves are durable: the accepting device retains its request until an inviter device handles it, and the inviter retains the resulting confirmation until the accepting device receives it. If a different inviter device receives the request before the newly issued link has synchronized to it, that device asks the sender to retry instead of treating the request as complete. Opening the same pending link again also retries it safely.
Replies are signed by the sender and encrypted to the recipient's key before
they leave the device. The mailbox stores only that ciphertext, for at most 30
days, with per-sender rate limits and per-recipient quotas. An account can opt
out of receiving mailbox messages (PUT /api/v1/mailbox/settings); invites then
still work whenever both parties share a connection or a mesh route.
Using the mailbox requires the account to be registered with peers.app (the
welcome screen or Identity → Account on desktop and PWA, --register-services
on a headless host). Registration issues a 30-day account token that the
runtime renews on its own: it re-authenticates with the account key a week
before the token expires, and once more if the service ever rejects the token
it holds. A user who never registered is never registered automatically.
None of this requires peers.app. Two devices on the same network, or any
chain of connected Peers devices, can complete every flow described here.
Each rung is exercised end to end by real processes in peers-e2e:
contacts-group.e2e.test.ts covers the direct and mesh paths with no cloud at
all, including an automatic group join that completes after its route returns.
invites-services.e2e.test.ts runs the real peers-services to cover the
mailbox while one party is offline, open-link admission through the mailbox,
the queued state during a service outage and its retry, and the relay between
two users who share no direct connection. See
End-to-end fleet testing.
Opening an invite link
https://peers.app/i#… opens a small page that reads the token from the
fragment on the client and offers:
- Open in Peers — a
peers://deep link for the installed desktop app; - Open in the web app — for the PWA;
- the token as a QR code and as copyable text for another device.
The page never sends the token anywhere. Inside the app, the token lands on the Accept an invite screen, which shows the inviter and the grant before you confirm.
Security notes
- A signed token proves who issued it; it does not prove who is holding it. Treat unused one-off links like a key and send them to one person.
- Accepting a contact invite sets a trust level you choose; the default is the lowest. Trust is always a local decision.
- Group approvals include the group's encryption secret boxed to the joiner, so a new member can read and write group data immediately. Only an Admin or Owner who holds the secret can produce an approval.
- Auto-admit links are re-verified by the inviter's device at join time: the signature, expiry, epoch, and the issuer's current role must all still be valid.