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

# Portkey

> Migrate from Portkey to Concentrate AI: what changes, what carries over, and what does not.

<Tabs>
  <Tab title="BYOK mode">
    <CodeGroup>
      ```python Python (OpenAI SDK) theme={null}
      # Before
      from openai import OpenAI
      import os

      client = OpenAI(
          base_url="https://api.portkey.ai/v1",
          api_key=os.environ["OPENAI_API_KEY"],
          default_headers={
              "x-portkey-api-key": os.environ["PORTKEY_API_KEY"],
              "x-portkey-provider": "openai",
          },
      )

      # After
      from openai import OpenAI
      import os

      client = OpenAI(
          base_url="https://api.concentrate.ai/v1",
          api_key=os.environ["CONCENTRATE_API_KEY"],
      )
      ```

      ```javascript JavaScript (OpenAI SDK) theme={null}
      // Before
      import OpenAI from "openai";

      const client = new OpenAI({
        baseURL: "https://api.portkey.ai/v1",
        apiKey: process.env.OPENAI_API_KEY,
        defaultHeaders: {
          "x-portkey-api-key": process.env.PORTKEY_API_KEY,
          "x-portkey-provider": "openai",
        },
      });

      // After
      const client = new OpenAI({
        baseURL: "https://api.concentrate.ai/v1",
        apiKey: process.env.CONCENTRATE_API_KEY,
      });
      ```

      ```bash cURL theme={null}
      # Before
      curl https://api.portkey.ai/v1/chat/completions \
        -H "Authorization: Bearer $OPENAI_API_KEY" \
        -H "x-portkey-api-key: $PORTKEY_API_KEY" \
        -H "x-portkey-provider: openai" \
        -H "Content-Type: application/json" \
        -d '{ "model": "gpt-4o", "messages": [...] }'

      # After
      curl https://api.concentrate.ai/v1/chat/completions \
        -H "Authorization: Bearer $CONCENTRATE_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{ "model": "gpt-4o", "messages": [...] }'
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Config-driven">
    <CodeGroup>
      ```python Python (OpenAI SDK) theme={null}
      # Before
      from openai import OpenAI
      import os

      client = OpenAI(
          base_url="https://api.portkey.ai/v1",
          api_key=os.environ["OPENAI_API_KEY"],
          default_headers={
              "x-portkey-api-key": os.environ["PORTKEY_API_KEY"],
              "x-portkey-config": "pc-prod-fallback",
          },
      )

      # After
      from openai import OpenAI
      import os

      client = OpenAI(
          base_url="https://api.concentrate.ai/v1",
          api_key=os.environ["CONCENTRATE_API_KEY"],
      )
      # Fallbacks / caching / retries move from the Config object to body params
      # on each request. See Step 4 for the mapping.
      ```

      ```javascript JavaScript (OpenAI SDK) theme={null}
      // Before
      import OpenAI from "openai";

      const client = new OpenAI({
        baseURL: "https://api.portkey.ai/v1",
        apiKey: process.env.OPENAI_API_KEY,
        defaultHeaders: {
          "x-portkey-api-key": process.env.PORTKEY_API_KEY,
          "x-portkey-config": "pc-prod-fallback",
        },
      });

      // After
      const client = new OpenAI({
        baseURL: "https://api.concentrate.ai/v1",
        apiKey: process.env.CONCENTRATE_API_KEY,
      });
      // Fallbacks / caching / retries move from the Config object to body params
      // on each request. See Step 4 for the mapping.
      ```

      ```bash cURL theme={null}
      # Before
      curl https://api.portkey.ai/v1/chat/completions \
        -H "Authorization: Bearer $OPENAI_API_KEY" \
        -H "x-portkey-api-key: $PORTKEY_API_KEY" \
        -H "x-portkey-config: pc-prod-fallback" \
        -H "Content-Type: application/json" \
        -d '{ "model": "gpt-4o", "messages": [...] }'

      # After
      curl https://api.concentrate.ai/v1/chat/completions \
        -H "Authorization: Bearer $CONCENTRATE_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{ "model": "gpt-4o", "messages": [...], "routing": { "model": { "fallbacks": ["..."] } } }'
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Prerequisites

<Steps>
  <Step title="A Concentrate AI account with an active API key">
    Sign up or log in at [concentrate.ai](https://concentrate.ai) and create an API key. Your key should start with `sk-cn-v1-`.
  </Step>

  <Step title="An existing Portkey integration">
    This guide assumes you are calling Portkey from the OpenAI SDK, the `portkey-ai` SDK, `fetch`, `requests`, or another HTTP client (in BYOK or Config-driven mode).
  </Step>
</Steps>

## Quick Start for Claude Code users

If you use [Claude Code](https://claude.com/claude-code), you can install a skill that walks through this migration interactively. It searches your project for Portkey usage, strips `x-portkey-*` headers, decomposes Configs, maps model slugs, and generates a verification script. Drop the skill into your `~/.claude/skills/` directory:

```bash theme={null}
mkdir -p ~/.claude/skills/migrate-portkey && \
  curl -fsSL https://concentrate.ai/scripts/migrate-portkey.md \
  -o ~/.claude/skills/migrate-portkey/SKILL.md
```

Then start a Claude Code session in your project and ask it to "migrate from Portkey to Concentrate" or run `/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:

```bash theme={null}
# Before (BYOK mode)
export PORTKEY_API_KEY="pk-..."
export OPENAI_API_KEY="sk-..."
export BASE_URL="https://api.portkey.ai/v1"

# After
export CONCENTRATE_API_KEY="sk-cn-v1-..."
export BASE_URL="https://api.concentrate.ai/v1"
```

<Warning>
  You no longer need `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, AWS credentials, Azure deployment IDs, or any other upstream provider key. Concentrate owns those credentials. Comment them out (don't delete) until you've verified the migration end-to-end, then remove them.
</Warning>

## Step 2: Update Your Client

The two big changes are the base URL and stripping every `x-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.

<CodeGroup>
  ```python Python (OpenAI SDK) theme={null}
  # Before (Portkey with portkey-ai SDK)
  from portkey_ai import Portkey

  client = Portkey(
      api_key=os.environ["PORTKEY_API_KEY"],
      virtual_key="openai-prod",
      trace_id="req_42",
      metadata={"_user": "user_42", "feature": "summarizer"},
  )

  # After (Concentrate)
  from openai import OpenAI
  import os

  client = OpenAI(
      base_url="https://api.concentrate.ai/v1",
      api_key=os.environ["CONCENTRATE_API_KEY"],
  )

  response = client.chat.completions.create(
      model="anthropic/claude-opus-4-6",
      messages=[{"role": "user", "content": "Say hello in one word"}],
  )
  print(response.choices[0].message.content)
  ```

  ```javascript JavaScript (OpenAI SDK) theme={null}
  // Before (Portkey with portkey-ai SDK)
  import Portkey from "portkey-ai";

  const client = new Portkey({
    apiKey: process.env.PORTKEY_API_KEY,
    virtualKey: "openai-prod",
    traceID: "req_42",
    metadata: { _user: "user_42", feature: "summarizer" },
  });

  // After (Concentrate)
  import OpenAI from "openai";

  const client = new OpenAI({
    baseURL: "https://api.concentrate.ai/v1",
    apiKey: process.env.CONCENTRATE_API_KEY,
  });

  const response = await client.chat.completions.create({
    model: "anthropic/claude-opus-4-6",
    messages: [{ role: "user", content: "Say hello in one word" }],
  });
  console.log(response.choices[0].message.content);
  ```

  ```bash cURL theme={null}
  curl https://api.concentrate.ai/v1/chat/completions \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $CONCENTRATE_API_KEY" \
    -d '{
      "model": "anthropic/claude-opus-4-6",
      "messages": [{"role": "user", "content": "Say hello in one word"}]
    }'
  ```
</CodeGroup>

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

<AccordionGroup>
  <Accordion title="Request header mapping" icon="arrow-right-arrow-left">
    | 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](#step-4-decompose-your-portkey-config) 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>`                                                                        |
  </Accordion>

  <Accordion title="`portkey-ai` SDK parameter equivalents" icon="code">
    If your code uses the `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                                             |
  </Accordion>

  <Accordion title="Response header mapping" icon="arrow-left">
    Portkey echoes a handful of headers back on every response. If your code reads or logs them, here's the 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](/docs/api-reference/endpoint/errors) for 429 semantics |
  </Accordion>
</AccordionGroup>

## Step 4: Decompose Your Portkey Config

Portkey's `x-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.

<Accordion title="Config key mapping" icon="arrow-right-arrow-left">
  | 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](/docs/api-reference/endpoint/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](/docs/api-reference/endpoint/guardrails-redaction)                      |
</Accordion>

<Warning>
  Concentrate has conditional routing, but it conditions on **request capabilities** (feature support, ZDR flag, per-feature uptime, cache affinity), not on **request attributes** (metadata, headers, user cohorts). If your Portkey Config routes on `_environment`, `_user`, or custom metadata, the migration path is to issue separate keys per condition and pick the key in application code.
</Warning>

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

If you were on Portkey with model strings like `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` |

Bare slugs work in all of these cases. Use them when you don't care which provider serves the request. Use the `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`](/docs/api-reference/endpoint/auto-routing) (`cost` / `latency` / `performance`) |

For the authoritative list of supported `provider/model-id` pairs, call [`GET /v1/models`](/docs/api-reference/endpoint/list-models) or browse the [Model Fortress](https://concentrate.ai/models).

## 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](https://concentrate.ai)                                                                       |
| Traces (`trace_id`-grouped)                             | `previous_response_id` on the [Responses API](/docs/api-reference/endpoint/create-response) 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](mailto:support@concentrate.ai) |
| Audit Logs                                | Available in the dashboard                                                                      |
| Prompts / Partials / Labels / Collections | No equivalent today                                                                             |
| Guardrails                                | [Guardrails & Redaction](/docs/api-reference/endpoint/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](/docs/api-reference/endpoint/create-response). It supports streaming, tool calling, structured output, multi-modal input, and web search through a single normalized shape across every provider, and `previous_response_id` replaces Portkey's `trace_id`-grouped sessions with a server-managed conversation tree.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.concentrate.ai/v1/responses \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $CONCENTRATE_API_KEY" \
    -d '{
      "model": "anthropic/claude-opus-4-6",
      "input": "What is the capital of France?"
    }'
  ```

  ```python Python theme={null}
  import os
  import requests

  response = requests.post(
      "https://api.concentrate.ai/v1/responses",
      headers={
          "Authorization": f"Bearer {os.environ['CONCENTRATE_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
          "model": "anthropic/claude-opus-4-6",
          "input": "What is the capital of France?",
      },
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.concentrate.ai/v1/responses", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.CONCENTRATE_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "anthropic/claude-opus-4-6",
      input: "What is the capital of France?",
    }),
  });
  console.log(await response.json());
  ```
</CodeGroup>

## Why migrate to Concentrate

<AccordionGroup>
  <Accordion title="How it works" icon="circle-info">
    Portkey offers two integration shapes. The migration path differs for each:

    * **BYOK mode.** Point the OpenAI SDK at `https://api.portkey.ai/v1`, set `x-portkey-api-key`, and pass your own provider key via `Authorization` (with `x-portkey-provider: openai`) or a stored Virtual Key (`x-portkey-virtual-key`, or `x-portkey-provider: @provider-slug`). **Migrating here gets you off provider keys entirely.**
    * **Config-driven mode.** Use `x-portkey-config` to 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](#step-4-decompose-your-portkey-config).
  </Accordion>

  <Accordion title="Team-scale spend management" icon="building">
    Concentrate organizes billing around an **organization → team → developer → key** hierarchy. Set budgets at any level and roll spend up into a single dashboard. Per-team budgets and per-developer attribution come from the key itself, so there's no per-request metadata tagging to maintain.
  </Accordion>

  <Accordion title="Feature-aware resiliency" icon="shield-check">
    Beyond ordered model and provider fallbacks (`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 to `json_object` or 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.

    All on by default. No Config object to author or version.
  </Accordion>

  <Accordion title="Strategy-driven auto routing" icon="route">
    `model: "auto"` accepts an explicit optimization target via `routing.model.sort`: `cost`, `latency`, or `performance` (default). See [Auto Routing](/docs/api-reference/endpoint/auto-routing).
  </Accordion>

  <Accordion title="Native Responses and Messages APIs" icon="code">
    Alongside OpenAI Chat Completions, Concentrate exposes a first-class [Responses API](/docs/api-reference/endpoint/create-response) and an Anthropic-compatible [Messages API](/docs/api-reference/endpoint/create-message).
  </Accordion>

  <Accordion title="Managed provider credentials by default" icon="key">
    Concentrate manages provider credentials by default. There are no Virtual Keys, Provider Integrations, or Model Catalog you must configure — point at a model and Concentrate owns the upstream credentials. If you'd rather keep using your own provider accounts, store those keys once in the dashboard with free [BYOK](/docs/api-reference/endpoint/byok) and routing uses them automatically.
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Model not found" icon="circle-question">
    Bare slugs (`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`](/docs/api-reference/endpoint/list-models) for the authoritative list.
  </Accordion>

  <Accordion title="Invalid API key error" icon="triangle-exclamation">
    Concentrate keys start with `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](https://concentrate.ai) and confirm there are no extra spaces or quotes.
  </Accordion>

  <Accordion title="Requests succeed but nothing shows up in the Concentrate dashboard" icon="chart-line">
    Confirm the base URL is `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.
  </Accordion>

  <Accordion title="My metadata filters stopped working" icon="tags">
    Concentrate does not accept arbitrary per-request metadata. Reserved Portkey keys like `_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.
  </Accordion>

  <Accordion title="My Config-based routing stopped applying" icon="route">
    `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](/docs/api-reference/endpoint/auto-routing). Conditional routing by metadata has no direct equivalent. Handle in application code.
  </Accordion>

  <Accordion title="Cache hit rate dropped after migrating" icon="database">
    Concentrate uses provider-native prompt caching, currently supported on Anthropic and AWS Bedrock. There is no semantic cache and no gateway-stored cache, so Portkey's `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`).
  </Accordion>

  <Accordion title="Connection errors" icon="wifi">
    Confirm the base URL is `https://api.concentrate.ai/v1` (no `/api` segment, no per-provider subdomain). Test the connection manually:

    ```bash theme={null}
    curl https://api.concentrate.ai/v1/responses/health
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="API Reference" icon="code" href="/docs/api-reference/introduction">
    Explore the full API capabilities
  </Card>

  <Card title="Available Models" icon="layer-group" href="/docs/api-reference/endpoint/list-models">
    Browse all supported models
  </Card>

  <Card title="Auto Routing" icon="route" href="/docs/api-reference/endpoint/auto-routing">
    Optimize model selection automatically
  </Card>

  <Card title="Get Support" icon="life-ring" href="mailto:support@concentrate.ai">
    Contact our support team
  </Card>
</CardGroup>

## Feedback

If you hit anything that didn't translate cleanly (especially around Configs, Prompt templates, conditional routing, custom hosts, or per-request metadata), email [support@concentrate.ai](mailto:support@concentrate.ai). The capability gaps called out above are tracked, and migration friction reports directly shape what we ship next.
