Client API Reference

The endpoints the SDKs call, for tokenizing text before it reaches your backend and revealing it on the way back. LLM traffic still goes through the proxy.

Authentication

Every call takes Authorization: Bearer <credential>, where the credential is a secret key, a publishable key, or a client session token. See Keys and reveal policy for what each may do. Optionally send X-NoPII-Session-Id to continue a session.

Client sessions

POST /v1/client-sessions

Secret key with client_session:create.

json
// Request
{ "end_user_id": "user-42", "ttl_seconds": 900 }

// Response
{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_at": "2026-09-16T01:34:07+00:00",
  "end_user_id": "user-42",
  "scopes": ["tokenize", "detokenize:own", "proxy:forward"]
}

Default lifetime 15 minutes, maximum 1 hour. Mint a new one to refresh.

GET /v1/client/session-info

The caller's tenant, kind, scopes, end user, and expiry.

Tokenize and detect

POST /v1/client/tokenize

Any credential with tokenize.

json
// Request
{ "texts": ["Call John Smith at john@example.com"], "session_id": "b7c1f0e2-...", "end_user_id": "user-42" }

// Response
{
  "texts": ["Call [NAME: aBcDeFgH] at [EMAIL: kLmNoPqR]"],
  "entities": [
    { "entity_type": "PERSON", "label": "NAME", "token": "aBcDeFgH", "score": 0.85,
      "masked_value": "J*********", "start": 5, "end": 15, "text_index": 0 }
  ],
  "tokens": { "aBcDeFgH": "John Smith", "kLmNoPqR": "john@example.com" },
  "session_id": "b7c1f0e2-...",
  "entity_count": 2
}

tokens maps back only values submitted in this call, so the caller can reveal them locally without another request. With a client session, the session's end user always wins over end_user_id in the body. Limits: 100 texts and 200,000 characters per call. Submitted text counts toward protected tokens.

POST /v1/client/detect

Same request. Entities come back with token: null. Nothing is tokenized, and it is not metered.

Reveal

POST /v1/client/detokenize

json
// Request
{ "tokens": ["aBcDeFgH"], "text": "Hello [NAME: aBcDeFgH]", "session_id": "b7c1f0e2-...", "grant_id": null }

// Response
{
  "tokens": { "aBcDeFgH": { "status": "revealed", "plaintext": "John Smith" } },
  "text": "Hello John Smith"
}

Status per token is revealed, forbidden, purged, or not_found, decided by the reveal policy. A partial result returns 200. Pass grant_id to use a reveal grant; an invalid one is refused with 403. Limit: 500 tokens per call.

GET /v1/client/pretext?labels=NAME,EMAIL

The system prompt that explains tokens to a model, for when you call an LLM directly with tokenized text. The proxy adds it for you.

Reveal grants

POST /v1/reveal-grants

Secret key with reveal_grant:create.

json
{
  "subject_end_user_id": "customer-42",
  "grantee_end_user_id": "support-agent-7",
  "ttl_seconds": 900,
  "reason": "ticket 4412"
}

Needs subject_end_user_id, tokens, or both. Returns the grant with its id, created_at, and expires_at.

DELETE /v1/reveal-grants/{grant_id}

Revokes the grant immediately. Idempotent.

Tokens-only proxy mode

Add X-NoPII-Mode: tokens-only to a proxy request whose messages are already tokenized. NoPII explains the tokens to the model, tokenizes anything that was missed, and returns the reply with tokens in place, streamed tool call arguments included. Pass the browser's X-NoPII-Session-Id so the user can reveal the reply.

Errors

StatusCause
401Missing, unknown, revoked, or expired credential. An expired session also sends X-NoPII-Error-Code: session_expired.
403Missing scope, or a publishable key used from an unlisted origin or with no Origin header
413Too many texts, characters, or tokens
429Rate limit exceeded
503Tokenization is unavailable. Nothing is returned, so partially protected text never reaches you.

Browsers can read X-NoPII-Session-Id, X-NoPII-Entity-Count, X-NoPII-Labels, and X-NoPII-Error-Code from responses.

Related