typed Privacy Policy
Effective date: 2026-10-08
Tier-aware sections: Several sections below distinguish between the solo tiers (Starter, Pro, Max -- single-user subscriptions, local-only codebase context) and the team tiers (Team, Team Max -- multi-user accounts with opt-in server-side hosted codebase indexing). The data we collect, process, store, and share is materially different between the two; the sections labeled "Team / Team Max only" apply only to customers who have explicitly subscribed to those tiers and uploaded codebases for indexing.
1. Who We Are
typed is a coding-assistant SaaS operated by Yaw Labs LLC (a California limited liability company, "Yaw Labs," "we," "us," "our"). typed lives at typed.cloud, app.typed.cloud, and api.typed.cloud. The public status page is at typed.cloud/status (status.typed.cloud is a legacy alias that 308-redirects to it). This Privacy Policy explains how we collect, use, share, and protect personal data when you use the typed service.
If you have questions, contact us at privacy@typed.cloud.
2. What This Policy Covers
This Privacy Policy covers:
- The typed marketing site (
typed.cloudand subdomains). - The typed dashboard (
app.typed.cloud). - The typed API endpoint (
api.typed.cloud). - The typed status page (
typed.cloud/status; the legacystatus.typed.cloudalias 308-redirects there). - Email and customer-support communications with typed.
It does NOT cover third-party services that you may use alongside typed (e.g., your coding CLI, your IDE, your git host). Those services have their own privacy policies.
2.1 The free local tier and the bring-your-own-key add-on: typed is not in the request path
typed runs two tier families, plus one add-on, and almost everything in this policy applies only to the first family.
- Paid, hosted (
typed++andtyped). Your requests reach typed's API, and from there the processors and cross-border flows described in §5 and §6. Until 20 September 2026 these two tiers were namedtyped++xhighandtyped++high; from 20 to 23 September 2026 the economy tier was namedtyped--. Those names still work and refer to the same two tiers,typed++andtypedrespectively. A third hosted tier,typed++max, was retired on 20 September 2026 and no longer accepts requests. - Free, local (
typed-local, and the legacy ids that resolve to it, such astyped-max). Inference runs against a model server on your own machine. The request never reaches typed's API, is never seen by typed, and is never forwarded to any processor in §5. It does not cross a border, because it does not leave your computer. Until 23 September 2026 this tier was namedtyped; a request fortypedsent to our hosted endpoint before that date was refused, not processed. Since 23 September 2026 a request fortypedis a request for the paid hosted economy tier above, and is processed as one. - Bring your own key (
typed-openrouter, a paid add-on, from 8 October 2026). The typed CLI on your machine sends the request directly to a model provider account that you hold, using your own key. The request never reaches typed's API, is never seen by typed, and is never forwarded to any processor in §5. typed does not hold, store or receive your key, and is not a party to that request: the provider account's own terms and data settings govern what happens to your prompts and code, including retention, training and where the data goes. The zero-data-retention and no-training commitment in §5.3 does not cover these requests.
Consequently, on the free local tier and on the bring-your-own-key add-on: no prompt or response content is transmitted to or processed by typed, and nothing is forwarded along the data flow in §5.1. A request that names the local id but is nonetheless sent to our hosted endpoint is refused, and the refused attempt is recorded with zero tokens (before 23 September 2026 such rows carry the identifier typed; we read them as typed-local). The free local tier also requires no account and no API key — if you never sign in, typed holds no account data about you under §3.1 either.
Two narrow exceptions, stated so the claim above is exact:
The launcher performs a version check against typed to learn whether a newer release is available (at most once a day, in the background). It carries no prompt content and no API key. It does report three things about the launcher itself, so that typed can tell how many free installs exist at all: the launcher version, an operating-system family (one of
darwin,linux,windows,other), and a first-run flag that is set only on a launcher's first-ever check. The operating-system family is reduced to one of those four words on your machine, before the request is sent — the full system string your computer would otherwise report never leaves it.These are stored as a daily counter — one running total per (date, launcher version, OS family) — and nothing else. The counter holds no IP address, no device or install identifier, no account link, and no value that could distinguish one machine from another or connect two checks to the same computer. Because the rows are counters rather than events, that is a property of the storage shape, not a policy we apply to it. Set
TYPED_NO_TELEMETRY=1to send none of it; the version check still works and typed records nothing.If you separately sign in to use a paid tier, the account data in §3.1 applies to that account, and any request you make on a paid tier is covered by the rest of this policy as normal.
The bring-your-own-key add-on is a subscription on your typed account, so its billing is account data under §3.1 like a plan's. Before it runs, the typed CLI asks typed whether your add-on is active, using your typed API key; that check carries no prompt content, no model choice and not your own provider key, and typed records nothing about it beyond what any authenticated API call leaves in our logs (§7). Your own provider key and the model you choose stay on your machine.
Where a section below says "when you use the typed API", it means a request that actually reaches typed — that is, a request on a paid hosted tier. A bring-your-own-key request is not one.
3. What Data We Collect
3.1 Account data
When you sign up, we collect:
- Email address (required for magic-link authentication and account recovery).
- Billing information (processed by our payment processor -- we do not store card details).
- API keys you generate (we store a salted hash, not the raw key).
3.2 Usage data
When you use the typed API, we record:
- Timestamp of each request.
- Internal model identifier used (
typed++ortyped). These are the paid hosted tiers, and they are the only ones whose records carry token counts and a charge. Records written before the September 2026 renames carry the identifier in use at the time:typed++xhigh,typed++high,typed--(20 to 23 September 2026), or the retiredtyped++max. The free local tier (typed-local, and the legacy ids that resolve to it) runs on your own machine and does not reach typed (see §2.1). A request that names the local id but is nonetheless sent to our hosted endpoint is refused, and the refused attempt is recorded with zero tokens (before 23 September 2026 such rows carry the identifiertyped; we read them astyped-local). Requests on the bring-your-own-key add-on (typed-openrouter) go from the typed CLI to your own provider account and never reach typed, so typed holds no usage record of them: no tokens, no model, no timing. A request naming that id that is nonetheless sent to our hosted endpoint is refused without being processed. - Input token count, output token count, cached token count.
- Internal routing identifier (which upstream model destination served the request -- for our ops visibility, never returned to you).
- Request latency.
- API key used (by hash reference).
- HTTP status code returned.
We do NOT store the content of your prompts or responses by default. See §3.4 for the limited exceptions.
3.3 Source code (solo tiers -- Starter / Pro / Max)
We do not store your source code. On the solo tiers, typed is pure routing; local context (file content, codebase indexing, retrieval) is handled by the client you use (the typed CLI, Claude Code, Cursor, Continue, Aider, or any other Anthropic-API-compatible client) on your machine. Whatever your client decides to include in a prompt does flow through us at request time (see §3.4), but we do not persistently store source code or build a server-side index of your repository on the solo tiers.
3.3a Source code (Team / Team Max only -- opt-in via subscription)
If you subscribe to a Team or Team Max tier and use the hosted codebase-indexing feature, the following applies. Subscribing to a Team-class tier IS the consent: by checking out a Team / Team Max plan you affirmatively authorize the processing described in this section. Customers on the solo tiers never trigger this surface.
You upload a codebase either from the typed dashboard or with typed codebase push in the typed CLI. Both drive the same three-step API flow:
POST /v1/codebasescreates the codebase record and returns a time-limited pre-signed upload URL (valid one hour).- Your client
PUTs a single compressed source archive (.tar.gz) directly to that URL. The archive travels from your machine to our object store; it does not pass through our API servers in transit. POST /v1/codebases/{id}/finalizemarks the upload complete and hands the archive to our indexer.
From that point:
- The uploaded source archive is stored at rest in our object storage, encrypted with AES-256. Our services reach it with credentials issued at runtime, not with long-lived access keys held on the machine.
- Per-codebase metadata is stored in the
codebasestable in our primary database (encrypted at rest per §9). Chunked source content and its embedding vectors are stored in thecodebase_chunkstable in the same database, with the embedding stored as avector(1024)column via the PostgreSQLpgvectorextension. - Not everything in the archive is indexed. Before any embedding call, our indexer withholds three categories of file: files that are credential stores by name (
.envand its variants,.npmrc,.netrc,.pgpass,.git-credentials,id_rsa,*.pem,credentials.jsonand similar); every dot-prefixed file outside a short allowlist of declarative project-config files (.gitignore,.editorconfig,.nvmrc, lint-config files and the like -- note that.env.exampleis deliberately NOT allowlisted); and any file whose contents carry a high-confidence secret shape, such as a PEM private-key block, a JSON Web Token, a recognizable provider key prefix, or anapi_key = ...style assignment. A withheld file is dropped whole: it is never chunked, never embedded, and never written tocodebase_chunks. - If you upload with the typed CLI, the same rules run on your machine first.
typed codebase pushapplies the credential-name, dotfile, and secret-content rules while it builds the archive, so a file the rules withhold is never written into the archive and never transmitted to us at all. The CLI prints what it withheld and why. An archive you build yourself and upload another way (including through the dashboard) skips that first layer; for those uploads the indexer filter above is the first place the rules apply. - The limit of that protection, stated plainly: these rules are heuristics over filenames and a set of well-known secret formats. A credential kept under an ordinary filename, in a format the patterns do not recognize, will not be caught, and will be chunked, embedded, and stored like any other source content. The filter reduces accidental exposure; it is not a guarantee that no secret can reach our index, and it is not a substitute for keeping credentials out of the repository you upload.
- What survives that filter is byte-window chunked (line-aligned, overlap) and embedded at indexing time (see §5.1). Document embeddings are persisted alongside the chunk text in
codebase_chunks. - At request time, when your client sends
x-typed-codebase: <id>on a/v1/messagescall, we embed the latest user-text turn as an ephemeral query embedding (never persisted), run a top-K nearest-neighbour search against the indexed codebase, select the most relevant chunks for your request, and inject those chunks into the inference request alongside your prompt.
What flows where:
- Codebase content at rest (the uploaded source archive in our object-storage bucket, the chunked text + embeddings in the
codebase_chunkstable) is stored only in our own object storage and database. It is not forwarded verbatim along the inference path. - Retrieved chunks (the small subset of codebase content that is most relevant to a given request) flow through the standard inference path described in §5.1, exactly like the rest of your prompt content. They are subject to the same zero-data-retention and no-training requirements (§5.3).
- Embeddings are computed outside our own infrastructure (see §5.1); the embedding request sends the chunk text (at indexing time) or the query text (at request time) for embedding generation. Document embeddings are persisted; query embeddings are ephemeral and discarded after the retrieval step.
- Access scope: codebase data is org-scoped. Only members of the org that owns a codebase can read, list, or delete it. A codebase belonging to org A is invisible to a user in org B even with the codebase's UUID.
Retention: codebase content is retained for the duration of your active Team / Team Max subscription, plus a 30-day grace post-cancellation that allows resubscription without re-upload. After the 30-day grace, the source archive in our object-storage bucket, the metadata in codebases, and the chunks + embeddings in codebase_chunks are hard-deleted within 14 days. You can delete any codebase yourself, immediately, at any time -- from the typed CLI or from the dashboard. §8 sets out the self-serve paths, exactly what deletion removes, and what we tell you if part of the cleanup has to be retried.
3.4 Prompt and response content (default OFF; opt-in only for support)
By default, we do not retain the content of your prompts or model responses. The internal proxy reads them in-memory to perform routing and translation, but discards them after the request completes.
Exceptions (opt-in only):
- If you explicitly request support for a specific request, we may retain that request's content for up to 30 days for debugging purposes. You opt in per-request when contacting support.
- Aggregate usage statistics (request counts, token counts, latency) are retained per §3.2 and do not contain content.
3.5 Launcher version-check counters (no account required, no identifier)
Separate from everything above, because it is the one thing typed records for people who have no account at all. When the launcher checks whether a newer release exists (at most once a day), it reports its own version, an operating-system family (darwin, linux, windows, other), and a flag set only on its first-ever check. The family is computed on your machine before the request goes out, so the detailed system string your computer could report is never transmitted.
We keep these as a running total per (date, launcher version, OS family) and nothing else. There is no row that represents you, your machine, or a single check: the storage is a counter that gets incremented, so two checks from one computer and one check from two computers are indistinguishable. No IP address, device identifier, install identifier, or account link is recorded, and none can be reconstructed from what is.
This is how we know how many free installs exist — the free local tier sends nothing else, by design (§2.1). Set TYPED_NO_TELEMETRY=1 to send none of it; the version check still tells you when your launcher is out of date.
4. How We Use Your Data
We use the data described in §3 to:
- Provide the typed service (route your requests, enforce quotas, bill correctly, surface usage metrics in your dashboard).
- Improve the service (debug failures, plan capacity, evaluate routing decisions). For this use, we use the metadata in §3.2, NOT the content in §3.4.
- Communicate with you (account notifications, billing notifications, security advisories).
- Comply with legal obligations (tax reporting, response to lawful process).
We do NOT:
- Train AI models on your prompts, responses, or code.
- Sell your data to third parties.
- Share your data with advertisers.
5. Third-Party Services in Our Data Flow
To deliver the typed service, your requests leave typed's own servers for embedding and for inference.
5.1 The data flow
When you make a request to api.typed.cloud:
typed (Yaw Labs LLC) -- US-based. Authenticates your request, enforces your quota, applies our coding-tuned system prompt, performs prompt-cache lookup.
Embedding. There are two distinct embedding flows:
- Knowledge layer (every paid tier, always on). The latest user-text turn of your prompt is embedded at request time to retrieve relevant snippets from a knowledge corpus typed authors and maintains. The matched snippets are prepended to your prompt before inference.
- Hosted codebase indexing (Team / Team Max only, opt-in via subscription). Source-code chunks you upload are embedded at upload time and persisted alongside the chunks in our
pgvectorindex (see §3.3a). Per-request queries are embedded at request time and discarded after the retrieval step. See §3.3a for the codebase-storage details and retention semantics.
Inference. The request is routed to an inference endpoint under the requirements in §5.3. Image content goes wherever the rest of the request goes: there is no separate image processor.
5.2 Cross-border data transfer
If you are located in the European Economic Area (EEA), the United Kingdom, or Switzerland, your request data is transferred outside the EEA, including to the United States.
This section covers requests on the paid hosted tiers only. A request on the free local tier never leaves your machine, and a request on the bring-your-own-key add-on goes from your machine to your own provider account under that account's terms; typed transfers neither (§2.1).
Tier-aware addendum (Team / Team Max). If you subscribe to a Team or Team Max tier and upload codebases for hosted indexing (per §3.3a), your codebase content at rest is stored only in our own object storage (archives) and database (metadata, chunks and chunk embeddings). Storage, chunking and the index stay on our own infrastructure: the indexer worker, the codebase_chunks table, and the pgvector index. The only codebase content that enters an inference request is the small subset of chunks that retrieval selects for that request -- those chunks travel through the same inference path as the rest of your prompt. Chunk text is also sent for embedding at indexing time, and query text at request time (§5.1).
We rely on the following lawful bases for these transfers under GDPR Article 49:
- Performance of a contract (Article 49.1.b) -- the transfer is necessary to provide the service you have purchased.
- Explicit consent (Article 49.1.a) -- by accepting this Privacy Policy at signup, you explicitly consent to the cross-border transfer described in this section.
We do NOT currently rely on Standard Contractual Clauses (SCCs) or adequacy decisions for these transfers. If transfer of your data outside the EEA is unacceptable for your use case, do not use typed for that work. We are working on offering an EU-routing-only tier in a future release.
5.3 Zero data retention and no training (key fact)
On the paid hosted tiers, every inference request is routed only to inference endpoints that have a zero-data-retention policy and that are not permitted to train on customer data. Both requirements are enforced on every request.
In plain English: at model inference, your prompts and code are processed under zero data retention and are never used for training.
This section is about model inference. It does not cover the embedding step in §5.1, or the codebase content we store for hosted indexing, which is kept as §3.3a sets out.
It also does not cover the bring-your-own-key add-on (typed-openrouter). Those requests go from the typed CLI to a provider account you hold, with your own key, and typed neither routes them nor sets their data-retention or training terms: your provider account's own settings do (§2.1).
If at any time these requirements cannot be satisfied for a specific request (e.g., the compliant endpoints are all unavailable), our system will return an error rather than fall back to a non-compliant endpoint.
5.4 Other third-party processors
In addition to the inference data flow, we use:
- A payment processor. Processes billing. Data sent: billing information, subscription state. We do not store card numbers.
- A transactional email service. Sends transactional email (magic-link sign-in, billing notices). Data sent: your email address + the email body.
6. Who We Share Your Data With
Beyond the third-party processors in §5, we share your data only:
- With your explicit consent (case-by-case).
- To comply with legal process (subpoena, court order, etc.).
- To protect our rights and safety (fraud prevention, abuse response).
- In connection with a merger, acquisition, or sale of business assets (we will notify you before such a transfer occurs).
We do not sell personal data.
7. Data Retention
| Data type | Retention |
|---|---|
| Account email + auth metadata | Until account deletion + 90 days |
| API keys (hashed) | Until you revoke; revoked keys retained for 90 days for audit |
| Usage records (timestamps, token counts, no content) | 24 months |
| Prompt / response content | Not retained, except per §3.4 opt-in for support (30 days max) |
Uploaded codebases (Team / Team Max only) -- source archive in our object storage, metadata in codebases table |
Active subscription + 30-day grace post-cancellation, then hard-deleted within 14 days |
Codebase embeddings (Team / Team Max only) -- codebase_chunks table, pgvector index |
Same as the codebase content -- deleted with the codebase |
| Billing records | 7 years (US tax law minimum) |
| Launcher version-check counters (§3.5 -- date, version, OS family; no identifier) | Indefinitely; they are aggregate totals with no personal data to expire |
| Server logs (request metadata, no content) | 30 days |
You can request deletion of your account at any time. We will delete account data within 30 days of your request, subject to legal-retention requirements (e.g., billing records). For uploaded codebases (Team / Team Max only), you can delete a specific codebase yourself, immediately, without affecting the rest of your account -- see §8.
8. Your Rights
If you are in the EEA, UK, or Switzerland, you have the following rights under GDPR:
- Access: request a copy of the personal data we hold about you.
- Rectification: correct inaccurate or incomplete data.
- Erasure ("right to be forgotten"): request deletion of your personal data.
- Restriction: ask us to limit how we process your data.
- Portability: receive a copy of your data in a portable format.
- Objection: object to certain types of processing (we honor opt-outs).
- Withdraw consent: if our processing relies on consent, withdraw it at any time (this does not affect processing before withdrawal).
If you are in California, you have analogous rights under the CCPA:
- Right to know what personal data we collect.
- Right to delete personal data.
- Right to opt out of "sale" of personal data (we do not sell).
- Right to non-discrimination for exercising these rights.
To exercise any of these rights, email privacy@typed.cloud from the email address on your typed account. We respond within 30 days for GDPR and 45 days for CCPA.
Team / Team Max codebase erasure (self-serve). You do not need to contact us to delete an uploaded codebase. Either of these removes one immediately, without affecting your account or your other codebases:
- typed CLI:
typed codebase rm <id>. It asks you to type the codebase id back before it does anything;--yesskips that prompt for scripted use. - Dashboard: the Delete control on the codebase row at
app.typed.cloud/dashboard/codebases, behind a confirmation dialog.
Both call the same endpoint (DELETE /v1/codebases/{id}), which does three things: it marks the codebases row deleted, so the codebase leaves your list and stops being retrievable into any request; it deletes that codebase's chunks and embeddings from codebase_chunks; and it deletes the uploaded source archive from our object-storage bucket. The chunk wipe and the archive delete run as separate steps from the first one.
We report a partial deletion as a partial deletion. If the chunk wipe or the archive delete does not complete, the codebase is still removed from your view and can no longer be retrieved into any request, but those rows or that archive still exist in our infrastructure for a period. We do not report that as a clean deletion: the API answers HTTP 207 naming the outstanding step, the CLI prints that some cleanup is still pending along with which steps, and the dashboard shows the same. The outstanding work is recorded and retried automatically by a background job; if it exhausts its retry budget, an operator completes it by hand. Email privacy@typed.cloud if you need written confirmation that a deferred step has completed.
Email remains available as a fallback: write to privacy@typed.cloud from the address on your account naming the codebase, and we will delete it for you. Deleted codebase content is removed from our rolling backups within 14 days.
9. Security
We protect your data with the following technical and organizational measures:
- TLS 1.3 in transit (enforced by Caddy at the ingress).
- AES-256 encryption at rest for our database, our object storage, and our cache.
- API keys stored as salted hashes, never in plaintext.
- Least-privilege service-account separation between the typed application and its infrastructure, with credentials issued at runtime -- our services hold no long-lived credential file.
- A managed secret store for third-party credentials.
- Zero-data-retention and no-training routing (§5.3), enforced on every inference request.
- Network policy isolation between typed and other workloads.
- Codebase content (Team / Team Max): source archives sit in our object storage (AES-256 at rest), and chunk embeddings sit in the
codebase_chunkstable via thepgvectorextension. Credential-shaped files are withheld from the index entirely (§3.3a). Access is gated by your tier subscription, your account credentials, and org-scoped read paths (only members of the org that owns a codebase can read or list it).
No system is perfectly secure. If you suspect unauthorized access to your account, contact security@typed.cloud immediately.
10. Cookies and Tracking
We use:
- Essential cookies -- session authentication on
app.typed.cloud. Cannot be disabled. - Functional cookies -- remembering UI preferences. Can be disabled in browser settings.
We do NOT use:
- Marketing cookies.
- Advertising tracking pixels.
- Third-party analytics that share data with advertisers.
For server-side analytics (request counts, page views, anonymized), we use our own infrastructure (Prometheus + internal aggregation). No third-party analytics provider sees identifiable data.
11. Children's Privacy
typed is not intended for children under 16. We do not knowingly collect personal data from children under 16. If you believe a child has provided data to us, contact privacy@typed.cloud for deletion.
12. Changes to This Policy
We may update this Privacy Policy. When we do, we post the updated version here with a new effective date.
The current version is always available at typed.cloud/privacy. Past versions are kept on request; email privacy@typed.cloud.
13. Contact
- General privacy questions:
privacy@typed.cloud - Security incidents:
security@typed.cloud - GDPR Data Protection Officer: Not currently appointed. Yaw Labs LLC does not meet the GDPR Article 37 mandatory-DPO thresholds (250+ employees, public-authority status, or large-scale systematic monitoring of data subjects). We will appoint a DPO if processing volume crosses those thresholds; the appointment will be reflected here.