SDKs
The drop-in proxy keeps PII away from the LLM provider. The SDKs go further: they tokenize messages in the user's browser, so your backend, database, and logs hold only tokens, and reveal them again when the reply reaches the user.
Preview
Who sees plaintext
Pick a tier by where you want plaintext to stop. Each tier includes the protection of the ones before it.
| Tier | How | LLM provider | Your backend | Your frontend |
|---|---|---|---|---|
| Proxy | Point your server's LLM client at NoPII | Tokens | Plaintext | Plaintext |
| Tier 1 | The browser SDK reroutes provider calls made from the page | Tokens | Not involved | Plaintext |
| Tier 2 | The browser SDK tokenizes requests to your own routes | Tokens | Tokens | Plaintext |
No tier takes your frontend out of scope. Your page's JavaScript runs on the same origin as the text the user types, so it can read it. Hosted input elements that close that gap are planned.
Choose a package
| Package | Runs in | Use it to |
|---|---|---|
| @nopii/browser | Browser | Tokenize requests to your routes, reroute provider calls, and reveal replies |
| @nopii/react | React apps | Wire the browser SDK into React and the Vercel AI SDK's useChat |
| @nopii/node | Node.js servers | Mint client sessions, forward tokens to the LLM through the proxy, tokenize for indexing |
| nopii-sdk | Python servers | The same as the Node.js SDK, for sync and async Python |
| @nopii/mock-server | Your machine | Develop and test offline against an in-memory NoPII |
How Tier 2 fits together
A typical chat app uses one SDK on each side.
Browser (@nopii/browser) Your server (@nopii/node or nopii-sdk) NoPII proxy
------------------------ --------------------------------------- -----------
1. Asks your server for a client session
2. Mints one with its secret key
3. Tokenizes the message with NoPII
4. POST /api/chat, tokens only -> 5. Forwards the tokens, tokens-only mode -> 6. Explains the tokens to
the model, calls it
7. Reveals the streamed reply <- 8. Streams the tokenized reply back <-
for the userYour server never handles plaintext in this flow. It stores tokens, logs tokens, and passes tokens to the model, which is told what each kind of token stands for so it can still reason about them.
Credentials
| Credential | Where it lives | Used for |
|---|---|---|
nsk_... | Your server only | Minting client sessions and reveal grants, server-side tokenization |
Client session | The browser or app, for up to an hour | Tokenizing and revealing as one of your end users. Recommended. |
npk_... | Embedded in a web page | Development and low-risk apps. Only works from the origins you list. |
Create keys under API Keys in the admin console. See Keys and reveal policy for what each can do.
Fail closed
When NoPII cannot be reached, the SDKs throw rather than send the request unprotected. A protected route always fails closed. Only provider interception can be told to fall back, with failOpen: true, and it should stay off, because it sends plaintext exactly when protection is broken.
Tokens reach your backend by design
[NAME: 8f2kQ1xZ]. Store them as they are. To show a user their own history later, return the tokens and let the SDK reveal them in the browser.Related
- Browser SDK: start here for a web app
- Keys and reveal policy: who may turn a token back into plaintext
- Client API reference: the endpoints the SDKs call