- BYOK mode
- Config-driven
Prerequisites
A Concentrate AI account with an active API key
sk-cn-v1-.Quick Start for Claude Code users
If you use Claude Code, you can install a skill that walks through this migration interactively. It searches your project for Portkey usage, stripsx-portkey-* headers, decomposes Configs, maps model slugs, and generates a verification script. Drop the skill into your ~/.claude/skills/ directory:
/migrate-portkey. Claude will load the skill and run the steps.
Step 1: Update Your Environment Variables
Replace your Portkey key and any upstream provider keys with a single Concentrate key:Step 2: Update Your Client
The two big changes are the base URL and stripping everyx-portkey-* header. If you were using the portkey-ai SDK, swap to the OpenAI SDK pointed at Concentrate. Concentrate does not ship a dedicated SDK because the OpenAI-compatible shape covers every endpoint.
Step 3: Remove x-portkey-* Headers
None of Portkey’s custom headers carry over to Concentrate, so they should come out. They’re dead weight in your client config and mislead future readers. Expand the tables below for the full mapping if any of these are in your code.
Request header mapping
Request header mapping
| Portkey header | Concentrate replacement |
|---|---|
x-portkey-api-key | Standard Authorization: Bearer sk-cn-v1-... |
x-portkey-provider, x-portkey-virtual-key | Drop. Provider is encoded in the model slug (provider/model-id); credentials are managed by Concentrate |
x-portkey-config | Drop. See Step 4 for per-feature mapping |
x-portkey-trace-id | Optional X-Request-Id for correlation. Concentrate returns its own request id on the response |
x-portkey-metadata | Drop. Use per-user, per-team, or per-org keys; analytics roll up by key automatically |
x-portkey-cache-force-refresh | No equivalent. Caching is provider-native, not gateway-stored |
x-portkey-cache-namespace | prompt_cache_key body param |
x-portkey-request-timeout | Set via your HTTP client (e.g. OpenAI SDK timeout) |
x-portkey-forward-headers, x-portkey-sensitive-headers | Not applicable. No BYOK passthrough |
x-portkey-custom-host | Not supported. Self-hosted models stay on direct calls |
x-portkey-azure-* | Drop. Request azure/<model-id> |
x-portkey-vertex-* | Drop. Request ai-studio/<model-id> or the appropriate Vertex-backed slug |
x-portkey-aws-* | Drop. Request bedrock/<model-id> |
`portkey-ai` SDK parameter equivalents
`portkey-ai` SDK parameter equivalents
portkey-ai SDK, the snake_case (Python) or camelCase (Node) parameters map to the same headers above:portkey-ai parameter | Header it sets | Concentrate replacement |
|---|---|---|
api_key / apiKey | x-portkey-api-key | OpenAI SDK api_key / apiKey with your sk-cn-v1- key |
virtual_key / virtualKey | x-portkey-virtual-key | Drop. Managed credentials |
config | x-portkey-config | Drop. Express settings as body params |
provider | x-portkey-provider | Drop. Model slug carries this |
trace_id / traceID | x-portkey-trace-id | Drop or send X-Request-Id |
metadata | x-portkey-metadata | Drop. Use per-key/team/org rollups |
cache_force_refresh / cacheForceRefresh | x-portkey-cache-force-refresh | Drop |
cache_namespace / cacheNamespace | x-portkey-cache-namespace | prompt_cache_key body param |
custom_host / customHost | x-portkey-custom-host | Not supported |
forward_headers / forwardHeaders | x-portkey-forward-headers | Not supported |
Response header mapping
Response header mapping
| Portkey response header | Concentrate equivalent |
|---|---|
x-portkey-trace-id | X-Request-Id (surfaced in dashboard logs) |
x-portkey-cache-status | Read usage.prompt_tokens_details.cached_tokens in the response body (where supported) |
x-portkey-provider, x-portkey-last-used-option-index | No header. Resolved provider is recorded per request in the dashboard |
| Rate-limit headers | Standard X-RateLimit-* headers. See Errors for 429 semantics |
Step 4: Decompose Your Portkey Config
Portkey’sx-portkey-config bundles caching, fallbacks, load balancing, retries, conditional routing, and timeouts into a single saved or inline object. Concentrate does not have a Config primitive. Each behavior is either on by default or expressed as a body param on the request. Expand the table below for the full mapping.
Config key mapping
Config key mapping
| Portkey config key | Concentrate equivalent |
|---|---|
strategy: { mode: "fallback" } + targets | routing.model.fallbacks or routing.provider.fallbacks, or model: "auto" |
strategy: { mode: "loadbalance" } + weighted targets | model: "auto" with routing.model.sort across eligible providers |
strategy: { mode: "conditional" } (route by metadata) | Capability-driven only. Issue different keys per condition and pick in application code |
cache: { mode: "simple" | "semantic", max_age } | Provider-native prompt caching. No semantic cache |
retry: { attempts, on_status_codes } | Automatic failover on any provider error across your fallback chain |
request_timeout | Set via your HTTP client |
override_params | Pass directly in the request body |
virtual_key inside a target | Drop. Managed credentials |
custom_host inside a target | Not supported |
guardrails | Guardrails & Redaction |
Step 5: Update Model Identifiers
Concentrate accepts model strings in two forms:- Bare slug, e.g.
gpt-4o,claude-haiku-4-5,auto. Routing picks a provider. provider/model-id, e.g.bedrock/claude-haiku-4-5,openai/gpt-4o. Pins the request to a specific provider.
gpt-4o or claude-sonnet-4-6 and provider selection via x-portkey-provider or a Virtual Key, drop the header and let the model slug carry provider intent. Most Portkey model strings work as-is once you remove the provider header.
One thing to know about the slashed form: the prefix is the provider that serves the request, not the model’s author.
Portkey customers steering through x-portkey-provider: bedrock (or a Bedrock Virtual Key) with model: "claude-sonnet-4-6" should switch to model: "bedrock/claude-haiku-4-5" (or whichever slug GET /v1/models returns). For most popular names the two are the same string (openai, anthropic, mistral), but they diverge whenever a model is hosted by something other than its author:
| Author | Provider serving the request | Concentrate slug |
|---|---|---|
Anthropic (claude-haiku-4-5) | Anthropic | anthropic/claude-haiku-4-5 |
| Anthropic (same model, different host) | AWS Bedrock | bedrock/claude-haiku-4-5 |
| Anthropic (same model, different host) | Azure | azure/claude-haiku-4-5 |
Google (gemini-3.5-flash) | Google AI Studio | ai-studio/gemini-3.5-flash |
Meta (llama-3-8b-instruct) | AWS Bedrock | bedrock/llama-3-8b-instruct |
provider/ prefix when you specifically want to pin to one host (for ZDR compliance, contractual reasons, or latency in a specific region).
The only universally required slug change is auto-routing:
| Portkey | Concentrate AI |
|---|---|
model: "auto" inside a Config strategy | model: "auto" with explicit routing.model.sort (cost / latency / performance) |
provider/model-id pairs, call GET /v1/models or browse the Model Fortress.
Step 6: Reconnect Observability
Concentrate’s dashboard covers the major surfaces you used in Portkey.| Portkey dashboard surface | Concentrate equivalent |
|---|---|
| Logs (full request/response) | Per-request logs at concentrate.ai |
Traces (trace_id-grouped) | previous_response_id on the Responses API links related requests into a stateful tree |
Metadata filters (_user, _environment, custom keys) | Per-user / team / organization keys. Analytics roll up by whichever key, team, or org the request was made with |
| Feedback API (thumbs up/down) | No equivalent today |
| Analytics (cost, latency, tokens, cache hit rate) | Org / team / developer / key spend and latency rollups |
| Rate Limits / Usage Limits Policies | Per-key rate and spend limits in the dashboard |
| Audit Logs | Available in the dashboard |
| Log Exports | Available via the dashboard |
Exporting your Portkey history
Portkey’s dashboards do not import into Concentrate, and the reverse is also true. Historical request logs stay where they were created. If your migration is driven by compliance or audit requirements, Portkey exposes Log Exports via their Admin API; pull your history out before deprovisioning your Portkey workspace.Step 7: Migrate Admin and Governance Surface
Portkey’s Admin API (Workspaces, Virtual Keys, Configs, Prompts, Policies, SCIM mappings) maps roughly to Concentrate’s organization/team/key hierarchy plus dashboard-managed settings rather than a separate API surface.| Portkey Admin concept | Concentrate equivalent |
|---|---|
| Workspace | Team (within an organization) |
| Virtual Key / Provider Integration | Not exposed. Managed credentials |
| Config | Body params per request |
| API Key | API Key (per developer, per team, or per org) |
| Rate Limits / Usage Limits Policy | Per-key rate and spend limits |
| User / User Invite / Workspace Member | Organization and team members in the dashboard |
| SCIM Workspace Mappings | Available for enterprise plans. Contact support@concentrate.ai |
| Audit Logs | Available in the dashboard |
| Prompts / Partials / Labels / Collections | No equivalent today |
| Guardrails | Guardrails & Redaction |
| Secret References | Not applicable. Concentrate owns provider credentials |
Step 8 (Optional): Adopt the Responses API
For new code, we recommend the native Responses API. It supports streaming, tool calling, structured output, multi-modal input, and web search through a single normalized shape across every provider, andprevious_response_id replaces Portkey’s trace_id-grouped sessions with a server-managed conversation tree.
Why migrate to Concentrate
How it works
How it works
- BYOK mode. Point the OpenAI SDK at
https://api.portkey.ai/v1, setx-portkey-api-key, and pass your own provider key viaAuthorization(withx-portkey-provider: openai) or a stored Virtual Key (x-portkey-virtual-key, orx-portkey-provider: @provider-slug). Migrating here gets you off provider keys entirely. - Config-driven mode. Use
x-portkey-configto reference a saved or inline JSON config covering caching, fallbacks, load balancing, retries, and timeouts. Decompose the Config: most settings become Concentrate body params or are handled automatically. See Step 4.
Team-scale spend management
Team-scale spend management
Feature-aware resiliency
Feature-aware resiliency
routing.model.fallbacks, routing.provider.fallbacks), Concentrate’s routing layer ships:- Uptime gate. Providers whose per-feature success rate drops below 90% are skipped.
- Feature degradation. If no provider supports the full requested feature set (e.g.
json_schema), the request is downgraded tojson_objector text instead of failing. - Cache-affinity routing. When multiple providers can serve a request, the one where your actor already has cached tokens is preferred.
Strategy-driven auto routing
Strategy-driven auto routing
model: "auto" accepts an explicit optimization target via routing.model.sort: cost, latency, or performance (default). See Auto Routing.Native Responses and Messages APIs
Native Responses and Messages APIs
Managed provider credentials by default
Managed provider credentials by default
OPENAI_API_KEY, ANTHROPIC_API_KEY, AWS keys, or Azure deployment IDs you carried alongside Portkey can be retired after migrating.Troubleshooting
Model not found
Model not found
gpt-4o, claude-haiku-4-5) and provider/model-id slugs both work. If you’re using a provider/ prefix and getting a miss, double-check the prefix is a provider (e.g. bedrock, azure, ai-studio) and not just the author (e.g. meta, google). Call GET /v1/models for the authoritative list.Invalid API key error
Invalid API key error
sk-cn-v1-. If you are still sending a Portkey x-portkey-api-key value (or an upstream provider key from BYOK mode) as the Authorization bearer, you will see a 401. Verify the value in your dashboard and confirm there are no extra spaces or quotes.Requests succeed but nothing shows up in the Concentrate dashboard
Requests succeed but nothing shows up in the Concentrate dashboard
https://api.concentrate.ai/v1, not api.portkey.ai. If the SDK is still pointed at Portkey it is logging against your Portkey workspace, not Concentrate.My metadata filters stopped working
My metadata filters stopped working
_user, _environment, and _organisation map to the key/team/org hierarchy. Issue a separate key per user or environment and analytics roll up automatically. Custom metadata keys have no equivalent today.My Config-based routing stopped applying
My Config-based routing stopped applying
x-portkey-config is a no-op on Concentrate. Express fallbacks via routing.model.fallbacks / routing.provider.fallbacks body params, or use model: "auto" with a routing strategy. Conditional routing by metadata has no direct equivalent. Handle in application code.Cache hit rate dropped after migrating
Cache hit rate dropped after migrating
simple and semantic cache modes do not carry over. Caches are seeded per API key by default; pass prompt_cache_key in the request body if you want to set the seed explicitly (the analog of x-portkey-cache-namespace).Connection errors
Connection errors
https://api.concentrate.ai/v1 (no /api segment, no per-provider subdomain). Test the connection manually: