Migration

Migrate to Privian

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

The short version

What is the problem?

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.

How is it solved?

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 should this approach be used?

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.

What are the limitations?

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

Before you migrate: compatibility checklist

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.

  • No native streaming — stream: true returns artificially chunked text, not a real provider token stream
  • No tool / function calling
  • No JSON mode
  • No multimodal input
  • No Responses API — Chat Completions shape only

Everything 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

Migrating from a direct OpenAI SDK integration

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

Migrating from another OpenAI-compatible gateway or proxy

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

Migrating from a bespoke in-house wrapper

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.content

If 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

A staged rollout, not a cutover

  1. 1

    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.

  2. 2

    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.

  3. 3

    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.

  4. 4

    Move the rest Repoint remaining OpenAI-compatible call sites that don't depend on unsupported beta features.

  5. 5

    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.

Each stage is reversible independently — you don't have to commit the whole integration before you've seen real traffic through the gateway.

Verification

How to verify masking is actually working

Don't take masking on faith — check it against your own traffic before you rely on it.

  • 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.

  • Inspect the outbound side

    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.

  • Check determinism within a request

    The same source value should map to the same placeholder throughout a single request, so the model can still reason about relationships between entities.

  • Confirm rehydration

    The response your application receives should contain the original value again, restored from the in-memory mapping for that request.

  • Test entity types you actually see

    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.

  • Re-check after any prompt-template change

    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

Rolling back

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

What does not change

  • Your provider account and billing

    You still hold your own OpenAI credentials under BYOK, and token usage still bills against your own account.

  • Your prompts

    Privian scans and masks the assembled prompt; it does not rewrite prompt content or logic beyond replacing detected values with placeholders.

  • Your response handling

    Rehydration happens inside Privian before the response is returned, so supported, non-streaming call sites receive an ordinary OpenAI-shaped response.

Provenance

About self-hosted proxy claims

Scope

What migrating to Privian does NOT solve

FAQ

Frequently asked questions

What does it take to migrate to Privian?
If your client already speaks the OpenAI Chat Completions shape, migration is a base URL and API key change: point the client at https://api.privian.io/v1, use a Privian gateway key, and address models as provider/model — for example openai/gpt-4o-mini. The blocker is not effort, it's whether your traffic depends on a beta limitation.
Can I migrate if I use streaming today?
Not yet without a change in behaviour. Privian's current beta does not support native provider token streaming, tool calling, JSON mode, multimodal input or the Responses API. If any of those are load-bearing for the feature you want to migrate, that feature should stay on its current path until the beta covers it.
Do I need to migrate everything at once?
No, and we recommend against it. Route one low-risk feature first, verify masking on real prompts, widen by feature flag, then move the rest. Nothing about the architecture requires an all-or-nothing cutover.
What happens to my OpenAI account and billing during migration?
Nothing changes there. Privian uses BYOK — your own OpenAI key, stored AES-GCM encrypted at rest and decrypted in-process at request time — so usage still bills against your existing provider account.
How do I verify masking is actually working after I switch?
Send prompts containing known test values for the entity types you care about and inspect what actually reaches the model, not just the response. Check that a supported value is replaced with a deterministic placeholder, that the same value maps to the same placeholder within a request, and that the response is rehydrated back to the original value on your side.
How do I roll back if migration doesn't work out?
Revert the base URL and API key back to the provider you were calling directly (or to your previous gateway). Because Privian does not persist raw prompts or responses, there is no data to migrate back — rollback is a configuration change, not a data operation.
I already run a self-hosted OpenAI-compatible proxy like LiteLLM. Why would I add Privian?
You would add Privian specifically if masking sensitive data before it leaves your boundary matters more than routing breadth or self-hosted control. A proxy like LiteLLM is a strong, purpose-built choice if breadth of provider routing or self-hosting is your priority; Privian is narrower and focuses on prompt-level data protection with one documented data path. See the LiteLLM comparison for the detailed trade-off.
Does migrating to Privian change my application's response handling?
No. Rehydration happens inside Privian before the response is returned, so your application receives an ordinary OpenAI-shaped response with real values. Response parsing code does not need to change for supported, non-streaming requests.
What if my in-house wrapper does more than call the API?
Anything your wrapper does around the call — retries, logging, prompt assembly, caching — keeps working unchanged. Only the outbound HTTP call needs to target Privian's base URL, provided the wrapper doesn't depend on streaming, tool calling, JSON mode, multimodal input or the Responses API.

Next

Plan the migration

Related

Related reading

Enterprise review

Built for enterprise review

Trust assets procurement and security teams routinely request.

Plans & pricing

Pricing for a migrated LLM gateway

BYOK, zero retention and masking before the provider call. Beta plans may change as the product matures.