We can't read
your calls.

This is the whole privacy model: what we store, what we never see, where plaintext goes when you ask, and how to check all of it yourself.

On your device

transcript“Then I can do 9,400 for the set, delivery included, if you confirm by Sunday.”
contactDana Levi · +972 50-555-0112
tagHot lead
when13 Nov 2026, 14:32 · 8 min 14 s

On our server

transcriptCt · AES-256-GCM01 3ec5dbab 3ac23d4e fdb1b67f d731c16b 6f645514 119720b9 9630ef67 98518d5a 7a867111 9beceeb3 be7161de … 983 bytes
contactTok · HMAC-SHA256, 64 bit-681415598111050068
tagToks[-3351592599059850810]
day · durationBucket20770 · 2

Real bytes: the sample call encrypted with the app's own code under a published demo key. Field names are the server's column names.

What we store, and what we never see.

Your device indexes and encrypts before anything leaves it. The server receives ciphertext and tokens, and returns them when you search.

The server stores

  • Encrypted transcripts, metadata, notes and recordings
  • HMAC tokens for keywords, contacts and tags
  • Embeddings of redacted text
  • The day of each call and a duration bucket
  • Wrapped keys and public keys

The server never sees

  • Transcript text or individual words
  • Phone numbers or contact names
  • Tag names, notes or rule definitions
  • Your keys, unwrapped
  • Decrypted recordings

Where plaintext goes.

Only for what you choose: a call you upload for transcription, a call you ask about, and the calls your translation rules cover. These routes stream straight through and never write to disk, storage or logs.

Transcription
deviceAskCallsElevenLabs

Audio of a call you upload. Where the provider issues single-use tokens, your browser sends the audio to it directly and our server never sees it; otherwise it streams through our server. With your own key, your device always sends it directly.

Ask about a call
deviceAskCallsAnthropic

That one call and your question, after you agree in a dialog that names the receiver. The transcript is wrapped as untrusted data, so instructions inside it aren't followed.

Translation
deviceAskCallsAnthropic

The transcript of each call your translation rules cover, as it uploads, so you can search it in the languages you chose. You set the rules in Settings → Providers, and the upload screen says it will happen; there is no prompt per call. With no rules nothing is sent. The transcript is wrapped as untrusted data, and the translation comes back to your device and is encrypted with the call. Your searches never leave your device.

Inbox uploads
remote AI toolAskCallssealed to your key

A transcript a remote AI tool sends for you is visible to our server in transit, sealed at once to your inbox public key, and the plaintext is discarded. The app says so next to each such item.

What each provider keeps

The terms each adapter works under, as documented in its README in the repository.

ProviderRetention
ElevenLabsWith zero retention turned on, requests carry enable_logging=false. ElevenLabs accepts it only on Enterprise plans; with it off, ElevenLabs keeps request logs under its standard policy.
DeepgramRequests carry mip_opt_out=true, opting out of Deepgram's Model Improvement Program; Deepgram then keeps the data only as long as needed to process the request.
OpenAI (transcription)No per-request retention flag. API inputs aren't used for training by default; zero data retention is an account-level agreement with OpenAI.
SonioxNo no-retention flag. The adapter deletes the uploaded file and the transcription as soon as it has the transcript; Soniox's 30-day expiry is the backstop.
AnthropicNo per-request retention flag; retention follows the instance's agreement with Anthropic.
OpenAI (questions)Requests send store: false, so the Responses API doesn't store them.
OpenAI-compatible, localOllama, LM Studio or a local Whisper server: requests stay on the network you run them on.

Your keys.

One root key is created on your first device and never leaves a device unwrapped. Every other key comes from it.

PasskeyWebAuthn PRF
Recovery code128-bit
PassphraseArgon2id
Linked deviceECDH P-256
each unwraps its own copy
Root key32 random bytes · wiped from memory on lock
HKDF-SHA256
kekAES-256-GCM
indexHMAC-SHA256
Per-call keytranscript, meta, snippets, recording
Tokenswords, contacts, tags · 64-bit

Unlocking.

Each method keeps its own wrapped copy of the root key. Sign-up can't finish until you create a recovery code and type part of it back.

Passkey
Face ID, Touch ID, Windows Hello or a security key. The PRF extension yields 32 bytes the server never sees.
Recovery code
8 groups of 4 characters, shown once. 128 bits of randomness, so no slow derivation is needed.
Passphrase
Only where the browser lacks PRF. Argon2id at 64 MiB, at least 12 characters.
Locking
After 15 idle minutes and on tab close. Keys and decrypted text are dropped from memory.

Verify what you run.

AskCalls builds reproducibly. Every release publishes the SHA-256 of each client JavaScript asset, so you can check that askcalls.com serves exactly the code in the repository. App routes load no third-party scripts and run under a strict CSP.

~
$ curl -s https://askcalls.com/_next/static/chunks/[asset].js | shasum -a 256
$ grep [asset].js SHA256SUMS
# the two hashes match

The leak test.

0 seeded words and phone numbers found in a full dump of the database and the storage bucket.

Every pull request runs it: seed calls with known words and numbers, dump the entire database and bucket, and search for them in UTF-8, UTF-16 and every normalized and token form. If anything turns up, the build fails.

Threat model and reporting.

AskCalls protects your calls from the server and anyone who gets at it. It can't protect what an unlocked device shows: a compromised device that is unlocked can read it. Report a vulnerability privately through the repository's security advisories, not in a public issue.

Ask your calls anything.