- OpenAI-compatible
- Native client (/inference)
Prerequisites
A Concentrate AI account with an active API key
sk-cn-v1-.An existing TensorZero integration
tensorzero client (POST /inference), the OpenAI SDK pointed at /openai/v1, fetch, requests, or another HTTP client.Quick Start for Claude Code users
If you use Claude Code, you can install a skill that walks through this migration interactively. It collapses the base URL, stripstensorzero:: model namespacing and body params, decomposes your tensorzero.toml functions and variants, maps model slugs, and generates a verification script. Drop the skill into your ~/.claude/skills/ directory:
/migrate-tensorzero. Claude will load the skill and run the steps.
Step 1: Update Your Environment Variables
TensorZero is self-hosted: provider credentials live in yourtensorzero.toml, and gateway auth (if enabled) uses TENSORZERO_API_KEY. All of that collapses to a single Concentrate key:
api_key sent by the client; it uses credentials from its own config. Concentrate requires a real sk-cn-v1-... key on every request, so make sure your client now sends one (not a placeholder).Step 2: Update Your Client
Collapse the gateway base URL (both the/openai/v1 and /inference paths) onto https://api.concentrate.ai/v1, and drop the tensorzero:: namespacing and body params. If you used the native tensorzero client, swap to the OpenAI SDK. Concentrate ships no dedicated SDK because the OpenAI-compatible shape covers every endpoint.
Step 3: Remove TensorZero-Specific Headers and Body Params
TensorZero keeps almost all of its distinctiveness intensorzero::-prefixed body params, not headers. None of them, nor TensorZero’s custom headers, carry over to Concentrate, so they should come out; they’re dead weight and mislead future readers. Expand the tables below for the mapping.
Request header mapping
Request header mapping
Request body param mapping (`tensorzero::*`)
Request body param mapping (`tensorzero::*`)
tensorzero::-prefixed body fields on the OpenAI endpoint (via extra_body), or as top-level fields (episode_id, variant_name, …) on /inference.Response field mapping
Response field mapping
Step 4: Decompose Functions, Variants, and Episodes
TensorZero’s defining concept is the function / variant / episode model intensorzero.toml: you call a named function, the gateway samples a variant (built-in A/B testing and fallbacks), and related inferences group into an episode. Concentrate has none of these primitives. Each behavior is either on by default or a body param. Expand the table for the mapping.
Function / variant / episode mapping
Function / variant / episode mapping
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.
tensorzero:: namespacing. Strip the tensorzero:: and model_name:: prefixes, and convert the provider::model double-colon to a provider/model slash. A function_name reference has no model string, so use the model its winning variant resolved to (see Step 4).
gcp_vertex_anthropic) already encodes the serving provider, so you just rename the prefix. For most popular names author and provider match (openai, anthropic, mistral), but they diverge whenever a model is hosted by something other than its author:
provider/ prefix when you specifically want to pin to one host (for ZDR compliance, contractual reasons, or latency in a specific region). To replace a configured model with provider fallbacks, use routing.model.fallbacks / routing.provider.fallbacks or model: "auto" (see Step 4).
For the authoritative list of supported provider/model-id pairs, call GET /v1/models or browse the Model Fortress.
Step 6: Reconnect Observability
TensorZero bundles observability, optimization, evaluations, and experimentation alongside the gateway (backed by ClickHouse). Concentrate’s dashboard covers the gateway-side surfaces; the experimentation and optimization tooling has no direct equivalent.Exporting your TensorZero history
Because TensorZero is self-hosted, your history lives in your own ClickHouse database and does not import into Concentrate. If your migration is compliance- or audit-driven, snapshot that data before tearing down the gateway.Step 7 (Optional): Adopt the Responses API
If you used TensorZero’s native/inference endpoint or its episodes, Concentrate’s native Responses API is the closest successor: streaming, tool calling, structured output, multi-modal input, and web search through one normalized shape across every provider, with previous_response_id replacing episode_id-grouped sessions.
Why migrate to Concentrate
How it works
How it works
tensorzero.toml, exposing several surfaces on one host. Migrating retires the process and config file and collapses every surface onto Concentrate’s single hosted base URL https://api.concentrate.ai/v1./inference endpoint is Responses-style (typed input, multi-step episodes). Its closest one-to-one target is Concentrate’s Responses API, reachable from the standard OpenAI SDK or any HTTP client.No gateway to run
No gateway to run
tensorzero.toml and provider credentials to maintain. Concentrate is hosted, with no gateway to operate, no config to version, and credentials managed for you.Team-scale spend management
Team-scale spend management
tags tagging to maintain.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.
tensorzero.toml to author, name, or version.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. This replaces hand-authoring a configured model with provider fallbacks in tensorzero.toml.Native Responses and Messages APIs
Native Responses and Messages APIs
/inference endpoint, Concentrate exposes a first-class Responses API. Alongside it you also get OpenAI Chat Completions compatibility and an Anthropic-compatible Messages API.Managed provider credentials by default
Managed provider credentials by default
tensorzero.toml (or TensorZero’s per-request credentials param), store them once in the dashboard with free BYOK — no gateway config to maintain.Troubleshooting
Model not found
Model not found
tensorzero:: and model_name:: prefixes and convert the provider::model double-colon to provider/model (e.g. tensorzero::model_name::openai::gpt-4o → openai/gpt-4o). Bare slugs (gpt-4o, claude-haiku-4-5) work too. 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-. TensorZero’s OpenAI-compatible endpoint ignored the client key, so your code may have been sending a placeholder (or a sk-t0-... gateway key). Concentrate requires a real sk-cn-v1-... key on every request. 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 localhost:3000. If the client is still pointed at your self-hosted gateway it is logging against your own ClickHouse store, not Concentrate.My functions / variants stopped working
My functions / variants stopped working
tensorzero::function_name::... and tensorzero::variant_name are no-ops on Concentrate; there is no function/variant config. Pin a model with model: "provider/model-id", express fallbacks via routing.model.fallbacks / routing.provider.fallbacks, or use model: "auto". Move function prompt templates into application code. Variant A/B sampling and the /feedback loop have no per-request equivalent, so handle the split in application code.My episodes / feedback stopped working
My episodes / feedback stopped working
episode_id body field or /feedback endpoint. Link related requests with previous_response_id on the Responses API. Evaluation feedback that fed TensorZero’s optimization stack should stay in your own tooling.Cache hit rate dropped after migrating
Cache hit rate dropped after migrating
max_age_s control, so TensorZero’s cache_options does not carry over directly. Caches are seeded per API key by default; pass prompt_cache_key in the request body if you want to set the seed explicitly.Connection errors
Connection errors
https://api.concentrate.ai/v1 (no /api segment, no /openai/v1 or /inference suffix, no localhost:3000). Test the connection manually:Next Steps
API Reference
Available Models
Auto Routing
Get Support
Feedback
If you hit anything that didn’t translate cleanly (especially around functions, variants, episodes, the feedback/experimentation loop,cache_options, or OTLP trace export), email support@concentrate.ai. The capability gaps called out above are tracked, and migration friction reports directly shape what we ship next.