> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from Portkey

> Concept-by-concept mapping from Portkey's virtual keys, configs and gateway to KnoxCall agents, routing policies and capability tokens — with before/after snippets and an honest account of what does not map.

# Migrating from Portkey

Portkey and KnoxCall overlap on the gateway itself — one endpoint in front of many
providers, with routing, fallbacks and observability — and diverge on where the
provider credential lives and what happens to the data passing through.

There is no automated importer for Portkey today (its configuration lives in a
hosted control plane rather than a file you can hand us), so this is a
concept-by-concept mapping you apply by hand. It is usually an afternoon.

## Concept mapping

| Portkey                   | KnoxCall                                                                                                                                 | Notes                                                                                     |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| Virtual key               | Agent + its upstream secret                                                                                                              | The agent is the thing you point an SDK at; the secret holds the provider key             |
| API key / auth header     | [Capability token](/ai-gateway/tokens-and-dpop)                                                                                          | Scoped to provider, model set, spend cap, IP range and time window, HMAC'd into the token |
| Config (routing)          | [`routing_policy`](/ai-gateway/routing-and-failover) on the agent                                                                        | Retries, backoff, weights                                                                 |
| Config (fallback targets) | `fallback_route_ids` + `route_weights`                                                                                                   | Fail-over order, or weighted split                                                        |
| Config (retries)          | `routing_policy.retry_on` + `max_attempts`                                                                                               | `429` must be named explicitly — see below                                                |
| Metadata                  | Agent `tags` + `X-KC-User` / `X-KC-Team` headers                                                                                         | Feeds per-user and per-team cost attribution                                              |
| Guardrails                | [Prompt firewall](/ai-gateway/firewall) + [PII detectors](/ai-gateway/pii-redaction) + [your own scanner](/ai-gateway/guardrail-webhook) |                                                                                           |
| Budget / usage limits     | `budget_daily_usd`, `budget_monthly_usd`                                                                                                 | Shared across workers, not per-process                                                    |
| Prompt templates          | *(no equivalent)*                                                                                                                        | Keep them in your application                                                             |

## Before / after

**Before** — Portkey-style, provider selection in a header or config id:

```python theme={"dark"}
from openai import OpenAI

client = OpenAI(
    base_url="https://api.portkey.ai/v1",
    api_key=PORTKEY_API_KEY,
    default_headers={"x-portkey-config": "pc-my-config-id"},
)
client.chat.completions.create(model="gpt-4o", messages=[...])
```

**After** — the agent *is* the config, so the base URL carries it:

```python theme={"dark"}
from openai import OpenAI

client = OpenAI(
    base_url="https://acme.knoxcall.com/v1/ai/support-bot/v1",
    api_key=KNOXCALL_CAPABILITY_TOKEN,
)
client.chat.completions.create(model="gpt-4o", messages=[...])
```

Nothing else in your code changes. The routing, the budget, the firewall and the
redaction all hang off `support-bot`, which means they are the same for every
caller of that agent rather than dependent on a header any caller can change.

## Three things that will surprise you

**A 429 is returned to you by default.** Portkey retries on rate limits out of the
box. KnoxCall does not, unless the agent's `routing_policy` names `"429"` in
`retry_on` — because silently absorbing a rate limit into a second provider's
bill is not a decision we make on your behalf. Set it explicitly:

```json theme={"dark"}
{ "routing_policy": { "retry_on": ["429", "5xx"], "max_attempts": 3 } }
```

**Your app stops holding a provider key entirely.** A Portkey virtual key still
resolves to a provider credential that the gateway sends onward; the difference
here is what your workload holds. A KnoxCall capability token is not a provider
credential and cannot be replayed against the provider — it only works against
your agent, and only within its scope.

**Prompt templates have no home here.** If you use Portkey's prompt management,
that stays in your application or in whichever tool you prefer. We are a gateway,
not a prompt store, and pretending otherwise would leave you with half a feature.

## What to do about the acquisition

Portkey is now part of Palo Alto Networks (Prisma AIRS). Whether that is good or
bad for you depends on whether you wanted a security-platform relationship, and it
is not our place to tell you it is bad. The practical question for a migration is
continuity of the specific features you rely on and of your commercial terms —
worth asking them directly before you plan around either.

## Suggested order

1. Create one agent per Portkey config, with its provider and a secret holding
   that provider key.
2. Mint one capability token per calling service — not one shared token. Scope
   each to the models that service actually uses. This is the step that pays for
   the migration.
3. Move `retry_on` / weights across into `routing_policy`.
4. Run both gateways in parallel behind a feature flag; compare
   `ai_gateway_usage` against your Portkey analytics for a week.
5. Turn on [PII redaction](/ai-gateway/pii-redaction) and a
   [firewall policy](/ai-gateway/firewall) in `warn` first, read the events for a
   few days, then move to `block`.

<Note>
  Step 5 in `warn` first is genuine advice, not a hedge. Turning a blocking control
  straight on in front of production traffic is how a good control gets switched
  back off after one bad afternoon.
</Note>
