Use known test values
Send prompts containing a test name, email or card number from the supported entity set and confirm you know exactly what was sent.
Migration
Switching an existing LLM integration to a privacy-first gateway.
If your application already calls an OpenAI-compatible endpoint, moving it behind Privian is usually a base URL and key change — provided you don't depend on a beta limitation. This page walks through compatibility, three migration paths, a staged rollout and rollback.
What does it take to route existing LLM traffic through Privian?
If you already use an OpenAI-compatible client, change the base URL to https://api.privian.io/v1 and swap in a Privian gateway key. That's the whole integration change — provided your traffic doesn't depend on streaming, tool calling, JSON mode, multimodal input or the Responses API, which the current beta does not support.
Summary
Teams already have working LLM integrations — direct SDK calls, another gateway, or an in-house wrapper — and want to add prompt-level data protection without rewriting how the application calls the model.
Point the existing OpenAI-compatible client at Privian's base URL with a Privian gateway key. Detection, masking and rehydration happen inside the gateway; the application code that assembles prompts and reads responses stays the same for supported, non-streaming requests.
When you want masking added to an existing OpenAI-compatible stack, when you're evaluating gateways and want a low-risk way to try one, or when a security review is asking what your application sends to a model provider.
Migration is only straightforward if your traffic doesn't rely on streaming, tool calling, JSON mode, multimodal input or the Responses API — none of which the current beta supports. Features that depend on them should stay on their current path.
Read this first
Start with what Privian's current beta does not do, not with what it does. If any of the following are load-bearing for the traffic you want to move, stop here for that traffic — migrate a different feature first, or wait.
stream: true returns artificially chunked text, not a real provider token streamEverything else on this page assumes the traffic you're migrating doesn't depend on the list above. The full current limitation set is maintained on the LLM Gateway page and in the API reference.
Path 1
If your application calls the OpenAI SDK directly today, the change is the client constructor: the base URL and the key. The rest of your call sites — message construction, response parsing — don't change for supported, non-streaming requests.
from openai import OpenAI
# Before
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# After
client = OpenAI(
base_url="https://api.privian.io/v1",
api_key=os.environ["PRIVIAN_GATEWAY_API_KEY"],
)
resp = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
)Your own OpenAI key is provided to Privian separately as a BYOK credential, stored AES-GCM encrypted at rest and decrypted in-process at request time — usage still bills against your OpenAI account.
Path 2
If you already run an OpenAI-compatible gateway or proxy — for example a self-hosted LiteLLM proxy — in front of the provider, the shape of the change is the same: repoint the base URL. What differs is what you're trading: a self-hosted proxy generally optimises for routing breadth across many providers and infrastructure control you operate yourself; Privian optimises for masking sensitive data before it leaves your boundary, as a hosted gateway.
from openai import OpenAI
# Before — pointed at a self-hosted proxy
client = OpenAI(
base_url="http://localhost:4000",
api_key=os.environ["PROXY_API_KEY"],
)
# After — pointed at Privian
client = OpenAI(
base_url="https://api.privian.io/v1",
api_key=os.environ["PRIVIAN_GATEWAY_API_KEY"],
)If your current setup depends on streaming, tool calling or multi-provider routing you rely on today, keep that traffic where it is and migrate a feature that doesn't need those first. See Privian vs LiteLLM for the full trade-off between routing breadth and prompt-level data protection.
Path 3
Many teams have a thin internal module that wraps the provider SDK — adding retries, logging, prompt templates or caching around a single outbound call. Migration only touches the outbound HTTP call itself; everything your wrapper does around it keeps working.
class LlmClient:
def __init__(self):
self._client = OpenAI(
base_url="https://api.privian.io/v1", # was the OpenAI default
api_key=os.environ["PRIVIAN_GATEWAY_API_KEY"], # was OPENAI_API_KEY
)
def complete(self, prompt: str) -> str:
# retry / logging / caching logic unchanged
resp = self._client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
)
return resp.choices[0].message.contentIf the wrapper's retry logic inspects streamed chunks or expects tool-call responses, that path needs to stay off Privian until those features are supported.
Rollout
Shadow a low-risk feature — Pick one feature with low blast radius — an internal tool or a non-critical path — and point only that call site at Privian.
Verify masking on real prompts — Run real (not synthetic-only) prompts through it and inspect what actually reaches the model, not just the response your application sees.
Widen by feature flag — Once verified, gate a larger share of that feature's traffic behind a flag rather than switching every caller at once.
Move the rest — Repoint remaining OpenAI-compatible call sites that don't depend on unsupported beta features.
Keep a documented fallback — Retain the previous base URL and key configuration, documented and ready, in case you need to revert a given call site.
Verification
Don't take masking on faith — check it against your own traffic before you rely on it.
Send prompts containing a test name, email or card number from the supported entity set and confirm you know exactly what was sent.
Confirm the value that reaches the model is a placeholder such as PERSON_1 or EMAIL_1, not the original value — not just that the response looks right.
The same source value should map to the same placeholder throughout a single request, so the model can still reason about relationships between entities.
The response your application receives should contain the original value again, restored from the in-memory mapping for that request.
Run this against the entity types that actually appear in your prompts, not just the examples in documentation — detection is best-effort over a supported set.
Because detection runs on the assembled prompt, a change to how you build prompts is worth re-verifying, not just a change to Privian.
The supported entity catalog and its known gaps are listed on the PII masking page.
Rollback
Rollback is a configuration change, not a data migration. Revert the base URL and API key back to the provider or gateway you were calling before. Because Privian does not persist raw prompts or responses — only structural counters are retained for billing and observability — there is no data on Privian's side to migrate back or reconcile.
Scope
You still hold your own OpenAI credentials under BYOK, and token usage still bills against your own account.
Privian scans and masks the assembled prompt; it does not rewrite prompt content or logic beyond replacing detected values with placeholders.
Rehydration happens inside Privian before the response is returned, so supported, non-streaming call sites receive an ordinary OpenAI-shaped response.
Provenance
Scope
FAQ
Enterprise review
Trust assets procurement and security teams routinely request.
Plans & pricing
BYOK, zero retention and masking before the provider call. Beta plans may change as the product matures.