How Stay actually works.
Stay's trust model depends on specifics, not vibes. This page documents exactly what the software does, what the network does, what we can see, and what we cannot. Every claim here is directly verifiable against the open-source code.
The short version
The stack
- Frontend: Next.js 16 (App Router) on React 19, styled with Tailwind CSS v4.
- Model: Anthropic Claude Sonnet 4.6, accessed via the official Anthropic SDK.
- Hosting: Vercel (serverless functions + edge middleware for rate limiting).
- DNS: Cloudflare, DNS-only mode (no proxying — Vercel handles TLS directly).
- Local storage: IndexedDB via the browser, with WebCrypto for encryption.
- Source: github.com/wudaming00/stay, MIT licensed.
What happens when you send a message
- Your browser posts to
/api/chatwith the recent message history (last 60 messages, capped at 80KB total). - Edge middleware checks your IP against an in-memory token bucket (30 requests per minute). Blocked requests get
429and the client shows the outage panel with crisis numbers. - The serverless function wraps your messages with the system prompt (cached by Anthropic for 5 minutes) and the tool definitions, then calls Anthropic's Messages API with streaming enabled.
- Anthropic's servers generate a response. Per Anthropic policy, the content is not used to train their models and is deleted within 30 days (unless flagged for abuse review).
- The stream comes back to our function, which re-encodes each text delta and tool-use block as an NDJSON line and streams it to your browser.
- Your browser appends each chunk to the visible message and, at the end, encrypts the full conversation using your device key and writes it to IndexedDB.
Encryption
- Algorithm:AES-GCM with 256-bit keys, via the browser's WebCrypto API.
- Key generation: On first use, your browser generates a random 256-bit key via
crypto.subtle.generateKey. The key is stored inlocalStorageon your device. - IV: A fresh 12-byte random IV is generated for every encryption via
crypto.getRandomValues. - Where ciphertext lives: IndexedDB on your device, keyed by session ID. Never on our servers.
- Scope: Anyone who can unlock this specific browser can read your conversations. We inherit the security model of your browser session — same as iMessage or email on this device.
What each party can see
| party | can see | cannot see |
|---|---|---|
| You (the user) | everything | nothing |
| Stay's server | IP + timestamp of API requests (for rate-limiting, not logged to durable storage) | message content, identity, past conversations |
| Anthropic | the system prompt + your messages in the current request, transiently, for <30 days | who you are, past conversations we didn't send |
| Vercel / Cloudflare | routing metadata (IP, TLS handshake, timestamps) | HTTPS-encrypted message content |
| Anyone on your browser | your encrypted conversations (the key is also on this browser) | (nothing — same as your other browser data) |
The safety mechanisms
- Crisis detection:The system prompt implements a Columbia-Protocol-style risk gradient for active suicidal ideation, Stanley-Brown Safety Planning (Stanley & Brown 2012; JAMA Psychiatry 2018), Campbell's Danger Assessment for DV including strangulation screening (Glass et al. 2008), and DBT-informed NSSI handling. See promises for the full list.
- Tool calling: Claude can surface crisis resources via
surface_resource, suggest a pause viasuggest_pause, reflect back user insights viaend_with_reflection, and produce a downloadable safety plan viagenerate_safety_plan. Phone numbers are hardcoded in the frontend — the model cannot hallucinate a number because it only references ids. - DV features:Quick-exit button + Escape key binding, panic-phrase option, neutral browser tab title (“Notes”), redirect to google.com and IndexedDB wipe on exit.
- Rate limiting: 30 requests per minute per IP via edge middleware. Prevents runaway cost and basic abuse.
What we do not do
- No analytics that identify users.
- No tracking pixels, no cookies for marketing purposes.
- No third-party advertisers, ever.
- No model fine-tuning on user conversations (we don't collect them).
- No sale or sharing of data. There is no data to sell.
Limits of the trust model
We want to be explicit about what this architecture doesn't protect against:
- If someone has physical access to your unlocked browser, they can read your conversations.
- Anthropic and Vercel are both subject to US legal process. They could be compelled to retain or produce data in transit, though Anthropic's stated retention is short (30 days).
- We can be compelled by legal process to change this product. If that ever happens, we will tell you before it takes effect, and our preference is to shut down an affected service rather than weaken its guarantees.
- AI responses can be wrong. Stay can misread your situation or say something unhelpful. If that happens, please tell us: hello@thestay.app.
The entire source is at github.com/wudaming00/stay. If any claim on this page is wrong — or if the code does something this page doesn't describe — please open an issue or email hello@thestay.app.