Registration & Account

Why no username and password?

During registration, the app receives a cryptographic Proof of Work challenge from the server and solves it — this prevents automated bot registrations. At the same time, unique device identifiers and several cryptographic key sets are generated on-device: long-term identity keys, signed prekeys, and one-time prekeys (including post-quantum ML-KEM-1024 keys). Only the public parts of these keys and the PoW result are sent to the server. Private keys never leave your device. There's no password: your account is defined by keys, and a 12-word recovery key brings it back on a new device.

Can I sign out and sign back in?

Yes, with your 12-word recovery key: on a new device or after reinstalling, choose Restore and enter the words. Your account and its address come back; old messages and sessions stay on the old device and do not move. Without those words, losing the device or deleting the app loses the account for good.

How do I keep my account when switching phones?

Your recovery key is created automatically when you register — there is nothing to do. You save its copy (12 words) later, from Settings: the app reminds you, and insists before you sign out. Until the copy is made the words are kept on the device, encrypted, and open only after Face ID, a fingerprint or the phone's passcode; once copied, they are erased from the device. Write them down and keep them somewhere safe — Konstruct has no phone number or email for you, so this is the only way back into your account.

Contacts

How do I message someone?

The system is designed so that a stranger cannot simply start messaging you. To start a conversation, one of you shares a QR code or an invite link and the other scans or follows it. Those are single-use: a QR code lives five minutes and a link twelve hours — a link that has been accepted once cannot be accepted again. Separately, you may switch on discovery in settings and be findable by username; that is off by default, so unless you turn it on, an invite is the only way in.

Why this restriction? Isn't it inconvenient?

It's an intentional design choice. In most messengers, knowing someone's phone number or username is enough to start flooding them with messages. Here, mutual consent is baked into the architecture — not just declared in a privacy policy.

What if someone shares my QR code without my permission?

A code can be accepted only once, so a shared link lets in at most one person, and a link that has already been used does nothing at all. It also stops working twelve hours after it was created — a QR code after five minutes. If someone does get in, you will see a new conversation and can block them immediately.

Encryption & Privacy

How does encryption work?

All messages are encrypted on the sender's device before transmission and can only be decrypted on the recipient's device. The server sees only an encrypted stream and routes it — it cannot read the content. Key establishment uses X3DH extended with post-quantum key agreement (PQXDH): the sender encapsulates an ML-KEM-1024 secret to the recipient's Kyber prekey, and that secret goes into the session's initial key alongside the classical ones, which is what limits "record now, decrypt with a quantum computer later". Post-quantum protection covers the very first message, and the app will not establish a session without it. Messages then use Double Ratchet, which rotates keys with every message — and each message also gets its own post-quantum key — so compromising one key exposes neither past nor future messages. Who sent a message is protected post-quantum too, and calls use post-quantum DTLS when both apps offer it. Still classical: the server's signatures (sender certificates, key-transparency heads), device sign-in and account recovery, Privacy Pass tokens and transport TLS; groups do not exist yet; the protocol specification lists every layer.

What exactly does the server see?

Very little, and none of it is you. To route a message the server needs an opaque account id for the recipient, the size of the ciphertext and the time it arrived; it also holds your public keys and, on iOS, a push token. That is the list. It does not see the content, your name, your avatar, your contact list — or, on the sealed-sender path that is always on, who sent the message. Messages are held only as ciphertext and removed on a retention schedule (about 7 days), not at the moment of delivery. A username is optional, is not used for routing, and is stored only as a keyed hash for the sole purpose of letting people find you — and that lookup is off until you switch discovery on, so by default an account cannot be found by name at all.

What about metadata? Who talks to whom?

This is the harder part. The server can still observe that someone delivered ciphertext to device B (recipient, time, size). With always-on Stealth (sealed sender), it does not learn who sent that ciphertext — see the next question. Censorship protection partially obscures the network path. Full anonymity at the routing layer (hiding from the recipient's side and from network-level IP/timing correlation too) is a problem of a different order of magnitude and isn't solved today.

Does the server know who sent a message?

No — the sender field is left out of the envelope, and this is always on for ordinary traffic (messages, delivery receipts, call setup, profile sharing). There is no switch to forget. Your device seals a signed sender certificate to the recipient's key: the recipient can open it and verify who wrote, the server cannot. A few internal paths — keep-alives, syncing your own devices, session housekeeping — still carry a sender by design.

It is worth being precise about what is being hidden, because it is not an identity. The server never had one: an account here is a keypair and an opaque id, with no phone number, email or real name attached, so there is nothing to link to a person in the first place. What sealed sender removes is the last link between two of those ids — who wrote to whom. The network layer is a separate matter and is covered above: timing and IP remain visible, and that is where a well-resourced observer works.

Limits: Stealth hides the sender identity from the server, not message timing, size, or your IP address — those remain visible at the network/transport layer. Privacy Pass tokens can ride along for anti-spam; server-side enforcement is still rolling out, so treat token-based rate control as maturing, not finished.

Do you collect analytics or telemetry?

No — none. No analytics, no usage metrics, no behavioural events, no crash phone-home, no advertising identifiers. Not "collected and anonymised" — not collected. The app has no third-party trackers (no Firebase, Crashlytics, Sentry, Amplitude, Segment); its only external dependencies are transport/media infrastructure and on iOS, an on-device speech-recognition library. Production builds also write no diagnostic logs to disk and expose no debug or log-export screen. When we need logs to fix a bug, it is you who taps "share" in a beta build — never a silent upload.

Profile

What is the Display Name for?

Your Display Name and avatar live on your device; they are not part of your public profile and nobody can look them up. When you start a new conversation the other person sees only a generated pseudonym, deterministic — always the same for a given ID. To show them your real name and photo, open their profile and turn on "Share my profile": both travel over the encrypted channel. One exception: if you send a contact request, your username and Display Name are attached to it so the recipient can tell who is asking. The server stores that snapshot encrypted at rest, under a key the server itself holds — it is not end-to-end encrypted, and your avatar is never included.

Why a generated name instead of just blank?

A blank name would be awkward — you'd see featureless rows in your chat list with no way to tell contacts apart. The generated name is stable: "Quick Falcon" is always "Quick Falcon" for that ID, on any device.

If someone has a username, do I see it?

Yes. Display priority: Display Name (if they shared it) → username → generated name. So if someone registered with @john, you'll see that, not "Peaceful Whale".

Messages

What do delivery status indicators mean?
  • Sending being encrypted on your device
  • Sent it left your device and the server accepted it
  • Delivered the recipient's device decrypted it and sent back a confirmation
  • Queued it has not gone out yet — the app keeps trying by itself; tap if you would rather not wait
  • Failed to send it was rejected for a reason retrying will not fix, so nothing happens automatically; tap to try again

There is no "read" status, and that is deliberate: a read receipt would tell the sender when you opened the app, which is a fact about you that the message does not need. "Delivered" is an encrypted receipt from the recipient's device — not the server saying it forwarded something.

Can I edit sent messages?

Yes, editing is supported. After changes, the message is marked as "edited". The edit propagates to the recipient's device through the same delivery mechanism as regular messages.

Why don't notifications arrive when the app is closed?

On iOS, notifications come through Apple Push Notification Service (APNs): a stable connection is needed, and in airplane mode, behind a VPN with aggressive filtering, or when Apple decides the push is "low priority", a notification may be delayed or not arrive. On Android there is no push service at all: the app keeps its own connection, shown by a persistent notification; aggressive battery saving or a blocked network can delay messages. When the app opens again, messages sync automatically.

Censorship protection

Does Konstruct work where messengers are blocked?

There is a censorship-protection mode that changes how the app reaches the network when a direct connection is blocked. In Settings it is a single control with three positions — off, automatic, on — and automatic is the default: the app uses a direct connection while it works and switches only on demonstrated failure. There is nothing to configure and no addresses to enter; setup happens in the background. The implementation is open source, so the design can be reviewed by anyone.

Is censorship protection always on?

By default it is automatic — a direct connection is faster, so the app uses it while it works and switches only when it demonstrably fails. You can also force it on or off. What we deliberately do not publish is which techniques are live and where they currently do or do not get through: a public, up-to-date status report is free feedback for whoever is doing the blocking, and the app itself shows none of it either, for the same reason.

Network Resilience & Sustainability

What happens if Konstruct's servers go offline?

Messaging stops until it returns. The alpha runs on a single trusted server, and there is no second path today — no relays, no peer-to-peer, no other instance to fall back to. Anything encrypted stays encrypted and nothing is lost; it simply will not move. Making that untrue is what the roadmap is about, and none of it has shipped.

Will basic messaging always be free?

Yes — unconditionally. Sending messages, receiving messages, E2EE, and all security features will never go behind a paywall. Donation-only models have historically proved fragile for privacy projects, so Konstruct plans a mix: voluntary donations, optional premium features (larger file transfers, extended history, themes — never security features), and B2B hosted instances for organizations. The core will always be free.

How is Konstruct funded? Can I donate?

No ads, no data resale, no telemetry — the flip side is that Konstruct runs on voluntary donations. They go directly to development and the server. Prefer Monero (XMR) if you care about privacy — unlike Bitcoin its chain isn't public. Always cross-check an address against the project repository before sending, in case a page is tampered with.

  • Monero (XMR) — recommended:
    496i5qvPzRtJPQjiPXnLvEGutjHFth4pWDQaJwbbMreyaTYg4qfbo48MXrTnYH32MHiAn5GcSEN1c48EYBvVkrx9Pi5BWvn
  • Bitcoin (BTC):
    bc1q5cthgu6k9utg9hk2mx2xshdtsrhvu54ysmqhmm
  • Ko-fi — convenient but not private, the processor knows your identity:
    ko-fi.com/construct_msg
What is P2P mode and when does it activate?

P2P mode is planned, not yet implemented — all traffic currently goes through the central server. The target design: when both users are simultaneously online and connected to a Konstruct server, the server will signal them to upgrade to a direct peer-to-peer QUIC connection. Once established, the server exits the message relay path — traffic flows directly between devices. If either side goes offline, delivery falls back to the server.

Security & Protection

What if strangers start mass-messaging me?

For this, the app has Lockdown mode. When enabled, notifications only come from people who were in your contacts at activation time. Messages from new senders are still saved — they just won't disturb you. Useful if you're a public figure and want to temporarily close off from new contacts.

What if one person starts spamming hundreds of messages?

If a suspiciously high number of messages arrives from a single sender in a short time (more than ~10 in 30 seconds), the client automatically shows a warning and mutes notifications from them. You can then either allow them or block them. Importantly: this is receiver-side protection and works regardless of what client the sender uses.

Technical

What is a "session" and why does it sometimes "break"?

A session is an established encrypted channel between two devices. It's built on one-time keys that can't be reused, and keys rotate with every message. If the app was inactive for a long time, the device was reinstalled, or the other person deleted the chat, an incoming message may be unreadable. The recipient's app then tells the sender's app which session state that message was written on; the sender's app opens a new state and sends the message again. Usually the user notices nothing — the message simply arrives.

Is multiple-device support available?

Linking a second device isn't available in public builds yet. The native desktop client is on hold; a terminal (TUI) client is in development. Since identity is tied to keys rather than a server account, multi-device support requires a separate key-binding mechanism — we're working on it.

What transport does Konstruct use for live messages?

Live messaging is a gRPC bidirectional MessageStream — one long-lived stream for heartbeats, inbound messages, and delivery receipts — not request/response polling. On current iOS builds the production path is QUIC (construct-transport); if QUIC is blocked or the handshake fails, the client falls back to gRPC over HTTP/2 + TLS 1.3 automatically. End-to-end encryption is independent of the transport: the wire only carries sealed ciphertext.

For Testers

What to check first?
  • Registration and adding a contact via QR code
  • Sending and receiving messages (both directions)
  • Delivery statuses — does a message reach "delivered", and do "queued" and "failed to send" retry when tapped?
  • Message editing — does the recipient see the changes?
  • Notifications with the app backgrounded
  • Behaviour with poor connectivity (airplane mode → restore)
  • Restoring the account from the recovery key after a reinstall
  • Saving the recovery key copy from Settings
How to report a bug?

In diagnostic (internal) builds the path is Settings → Diagnostics & logs → Share logs. Public builds keep no logs and do not compile that screen at all — if your build has no such row, describe the scenario and we will get a diagnostic build to you. The more precise the description (what you did, what you expected, what happened), the faster we can investigate. For a session issue, include logs from both devices.

Why are there so many repeated lines in the logs?

In debug builds some components log on every UI update — that is normal for development. Lines like FRC updated: 69 message(s) in window are the chat list refreshing and do not indicate a problem.