Client integrations¶
This page is for the question:
"My team has an application that uses SDK X and a framework like LangChain. How do they point at the control plane, and what works out of the box?"
The short answer: The VIDAI Control Plane is wire-compatible with the OpenAI, Anthropic, and Google GenAI SDKs. Most applications just need to change two settings (the base URL and the API key) and everything else (chat, tools, streaming, vision, caching markers) works as the SDK's own documentation describes.
The longer answer covers which SDK pairs with which upstream provider, what's known to work with the popular agent frameworks, and the limitations to plan around.
When you'd open this page¶
- An application team asks "where do we point our OpenAI SDK?"
- Someone wants to use the Anthropic SDK against a non-Anthropic upstream and asks if that works.
- Your platform team is evaluating whether to put the VIDAI Control Plane in front of an existing LangChain / LlamaIndex / ADK setup.
- You're checking whether a specific SDK feature (tool calling with streaming, vision, web-search beta tools, computer-use) works in your topology.
- A support ticket mentions a
404or400from the control plane and you want to know if the SDK × upstream pairing is supported.
The page at a glance¶
There are three ways to think about client integrations, and this page covers them in order:
- Pointing the SDK at the control plane: base URL + API key. The same shape for every supported SDK; only the variable names differ.
- What pairs with what: the SDK × upstream matrix. Every cell is "your SDK call ends up at the right upstream and the response shape matches what the SDK expects."
- Framework integrations: LangChain, LlamaIndex, Google ADK, etc. Most "just work" because they speak one of the supported SDKs underneath; the testcompat team verifies the non-obvious cases. Coverage table below; see the 🚧 placeholder sections for items pending verification.
1. Pointing an SDK at the VIDAI Control Plane¶
Two things change in your application config:
- Base URL → your control plane admin tells you the
hostname. Typically
https://<your-vidai-server>or an internal hostname for self-hosted deployments. The control plane exposes the same path layout the upstream SDKs already know:/v1/chat/completionsfor OpenAI,/v1/messagesfor Anthropic,/v1beta/models/<model>:generateContentfor Google GenAI. - API key → an API key you minted for the application or agent on the API Keys page. Use that instead of the upstream provider's key; the control plane handles the upstream auth on your behalf. (For the upstream-side setup (adding a provider, the URL where you grab the upstream API key) see the Provider catalogue.)
OpenAI SDK¶
from openai import OpenAI
client = OpenAI(
base_url="https://your-vidai-server/v1",
api_key="vidai-key-...", # your VIDAI key, not your OpenAI key
)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://your-vidai-server/v1",
apiKey: "vidai-key-...",
});
Anthropic SDK¶
import anthropic
client = anthropic.Anthropic(
base_url="https://your-vidai-server",
api_key="vidai-key-...",
)
📌 Worth knowing. The Anthropic SDK uses
/v1/messages, not/v1/chat/completions. The control plane exposes both shapes; your SDK picks the right one automatically.
Google GenAI SDK¶
from google import genai
client = genai.Client(
api_key="vidai-key-...",
http_options={"base_url": "https://your-vidai-server"},
)
For Vertex AI mode (vertexai=True), the same base URL
applies; the control plane handles the OAuth/JWT exchange to
the actual Vertex backend.
Raw HTTP / OpenAI-compatible clients¶
Anything that speaks "OpenAI HTTP" works against
/v1/chat/completions with Authorization: Bearer <vidai-key>.
⚠️ Watch out. Don't put the upstream provider's API key in your client config. The whole point of the control plane is that your application only ever sees the VIDAI key; the control plane holds the upstream credentials centrally on the Providers page.
2. SDK × upstream support¶
This is the customer-facing version of the support matrix. A ✅ means "your SDK call lands at the right upstream and the response shape matches what your SDK expects."
| Your SDK | OpenAI upstream | Azure OpenAI | Anthropic | AWS Bedrock | Google Gemini | Google Vertex AI |
|---|---|---|---|---|---|---|
| OpenAI SDK | ✅ | ✅ | ✅ | ⚠️ ¹ | ✅ | ✅ |
| Anthropic SDK | ✅ ² | ✅ ² | ✅ | ✅ ³ | ✅ ² | ✅ ² |
| Google GenAI SDK | ✅ | ✅ | ✅ | ⚠️ ¹ | ✅ | ✅ |
| Raw HTTP (OpenAI-compatible) | ✅ | ✅ | ✅ | ⚠️ ¹ | ✅ | ✅ |
Footnotes:
- ¹ AWS Bedrock supports Anthropic Claude models only. Other Bedrock-hosted families (Llama, Mistral, Cohere, Titan) aren't supported. Point those at a different upstream.
- ² Anthropic SDK to non-Anthropic upstreams is supported.
Older control plane versions returned
404for these pairs; if you see that, ask your admin to upgrade to a current release. - ³ Bedrock-Claude is reached natively when the Anthropic SDK is configured for a Bedrock-routed model. No translation needed; the wire formats match.
What "supported" actually means¶
For each cell marked ✅, the following SDK features work:
- Chat / messages /
generateContent(non-streaming + streaming) - Tool calling (single, parallel, multi-turn round-trips)
- System prompts (string OR text-block-array shape)
- Vision (base64 images, image URLs)
metadata.user_id/ OpenAIusermapping for taggingthinkingbudget / OpenAIreasoning.effortmapping- Anthropic-beta tools (
web_search_20250305,computer_20241022) on OpenAI upstream
If a feature isn't listed here, the SDK call still goes through, but the control plane doesn't promise the upstream-side behaviour matches the SDK's docs in every edge case. When in doubt, Request Logs shows the exact upstream response the control plane returned to your application.
💡 Pro tip.
cache_controlmarkers in the Anthropic SDK are silently stripped on non-Anthropic upstreams (the upstream doesn't have a cache concept). Your call still succeeds; the cache hint just doesn't do anything.
3. Framework integrations¶
Pick your framework below and follow its per-page guide. Each page is a developer recipe — TL;DR, prerequisites, walkthrough, and a probe you can run to confirm your setup works.
Provider SDKs¶
| SDK | Guide |
|---|---|
| OpenAI SDK (Python, JS) | integrations/openai-sdk.md |
| Anthropic SDK (Python, JS) | integrations/anthropic-sdk.md |
| google-genai SDK (Python, JS) | integrations/google-genai-sdk.md |
Agent frameworks¶
| Framework | Guide |
|---|---|
| OpenAI Agents SDK | integrations/openai-agents-sdk.md |
| Claude Agent SDK | integrations/claude-agent-sdk.md |
| Google ADK | integrations/google-adk.md |
| CrewAI | integrations/crewai.md |
| AutoGen (Microsoft) | integrations/autogen.md |
| Pydantic AI | integrations/pydantic-ai.md |
| LangGraph | integrations/langgraph.md |
LLM utility libraries¶
| Library | Guide |
|---|---|
| LangChain | integrations/langchain.md |
| LlamaIndex | integrations/llamaindex.md |
| Instructor | integrations/instructor.md |
| DSPy | integrations/dspy.md |
| Guidance | integrations/guidance.md |
| Marvin | integrations/marvin.md |
Enterprise frameworks¶
| Framework | Guide |
|---|---|
Databricks Genie (+ ai_query, Mosaic AI, Playground) |
integrations/databricks-genie.md |
| AWS Bedrock Agents | integrations/aws-bedrock-agents.md |
| Vertex AI Agent Builder | integrations/vertex-agent-builder.md |
| Azure AI Foundry | integrations/azure-ai-foundry.md |
| Semantic Kernel (.NET, Python) | integrations/semantic-kernel.md |
| Haystack (deepset) | integrations/haystack.md |
Code assistants & IDEs¶
| Tool | Guide |
|---|---|
| Cursor | integrations/cursor.md |
| Windsurf | integrations/windsurf.md |
| Zed | integrations/zed.md |
| Aider | integrations/aider.md |
| Cline | integrations/cline.md |
| Continue (continue.dev) | integrations/continue.md |
| Roo Code | integrations/roo-code.md |
Chat UIs (self-hosted)¶
| App | Guide |
|---|---|
| LibreChat | integrations/librechat.md |
| Open WebUI | integrations/open-webui.md |
| AnythingLLM | integrations/anythingllm.md |
| Chatbox | integrations/chatbox.md |
| Jan | integrations/jan.md |
| Msty | integrations/msty.md |
Low-code & automation¶
| Platform | Guide |
|---|---|
| n8n | integrations/n8n.md |
| Zapier | integrations/zapier.md |
| Make (Integromat) | integrations/make.md |
| Retool | integrations/retool.md |
Team-channel bots¶
| Platform | Guide |
|---|---|
| Slack apps | integrations/slack.md |
| Discord bots | integrations/discord.md |
| Microsoft Teams | integrations/microsoft-teams.md |
Notebooks¶
| Tool | Guide |
|---|---|
| JupyterAI | integrations/jupyter-ai.md |
| Google Colab | integrations/google-colab.md |
OpenAI API-spec compatibility¶
| Spec | Guide |
|---|---|
| Responses API | integrations/openai-responses-api.md |
| Assistants API | integrations/openai-assistants-api.md |
| Realtime API | integrations/openai-realtime-api.md |
| Batches API | integrations/openai-batches-api.md |
Model Context Protocol¶
| Spec | Guide |
|---|---|
| MCP | integrations/mcp.md |
If your framework isn't listed¶
If you use a framework that isn't listed above, chances are it
already works — most speak the OpenAI or Anthropic wire shape
underneath. Point the framework's model client at the control
plane using its native config surface (base_url / apiBase /
endpoint / openai_api_base) with your VIDAI API key and it
should just go.
If something's off — the framework doesn't accept a custom base URL, or a specific feature breaks — raise an issue at github.com/vidaiUK/vidai-quickstart/issues and we'll add a per-framework page (or a workaround).
⚠️ Watch out. Frameworks sometimes embed their own retry / fallback logic that conflicts with the control plane's Fallback chains. If you want the control plane to handle retries, disable the framework's built-in retries so the control plane sees the first failure and fires its fallback. Otherwise the framework retries first, the control plane sees the second-attempt success, and your fallback chain never runs.
Reference¶
Endpoints exposed to clients¶
| Path | Used by | Notes |
|---|---|---|
/v1/chat/completions |
OpenAI SDK, OpenAI-compatible clients | Streaming + tools + vision + reasoning |
/v1/messages |
Anthropic SDK | Streaming + tools + vision + cache markers (cache markers are no-ops on non-Anthropic upstreams) |
/v1beta/models/<model>:generateContent |
Google GenAI SDK (non-Vertex) | Streaming + tools + vision |
/v1beta/models/<model>:streamGenerateContent |
Google GenAI SDK | SSE streaming variant |
Vertex paths (/v1/projects/.../locations/.../publishers/...) |
Google GenAI SDK with vertexai=True, ADK |
OAuth/JWT handled by VIDAI |
SDK-level model discovery¶
Most LLM SDKs let the client list available models: OpenAI's
client.models.list(), Anthropic's client.models.list(),
Google GenAI's client.list_models(). When pointed at VIDAI
Server, those calls route through the same proxy and return
only the models the calling key is entitled to use (per the
key's allowed_models allowlist). Each SDK gets the response
in its own native shape:
| SDK | Endpoint | Response shape |
|---|---|---|
| OpenAI | GET /v1/models |
{data: [{id, object: "model", created, owned_by}], object: "list"} |
| Anthropic | GET /v1/models (detected via anthropic-version header) |
{data: [{type: "model", id, display_name, created_at}], has_more, first_id, last_id} |
| Google GenAI | GET /v1beta/models |
{models: [{name: "models/...", displayName, version, supportedGenerationMethods}]} |
A key with no allowed_models set (the default) sees every
model registered in the control plane. A key with an allowlist sees
only that subset. Aliases are returned alongside their canonical
names where applicable.
This means client-side "model picker" UIs in your applications will only show what the calling key can actually use: no misinformation about what's available, no "NotEntitledToCallModel" errors when the user picks something they shouldn't have seen.
Auth header¶
Every request carries Authorization: Bearer <vidai-key>. The
key is one you minted on the API Keys page; it
maps inside the control plane to a user or agent identity, which
in turn drives:
- Allowed models: what the key can call. Also drives what discovery returns (above).
- Routing rules scoped to the key's owner.
- Rate limits per key or per role.
- Guardrails inherited from the user / agent / group / key.
What VIDAI returns when something fails¶
The control plane tries to surface the upstream's own error shape
where possible (so your existing SDK error handling works
without changes). Control-plane-specific errors come back with a
distinguishable x-vidai-error-code header:
| Header value | Meaning |
|---|---|
key_not_found / key_disabled |
The key is missing, revoked, or disabled. |
model_not_allowed |
The key isn't allowed to call this model; see API Keys. |
rate_limited |
Per-key or per-role RPM cap hit; see Rate Limits. |
content_guardrail_blocked |
A guardrail rule denied the call; see Guardrails. |
routing_denied |
A deny rule matched; see Routing. |
upstream_unavailable |
All providers and fallbacks failed. |
Common questions¶
Do we need to change our application code to use the VIDAI Control Plane?
Almost never. The base URL and the API key change in your client config; everything else is the SDK speaking to the control plane as if it were the upstream provider.
Can the same application use multiple SDKs at once?
Yes. A single VIDAI key can serve OpenAI SDK calls and Anthropic SDK calls at the same time; just route each SDK to its respective base URL path (
/v1/chat/completionsand/v1/messages). The control plane handles auth and routing per request.What happens if I use the OpenAI SDK to call a Claude model?
The control plane translates the request into Anthropic's wire format on the way out and translates the response back into OpenAI's shape on the way back. Your SDK sees a standard OpenAI response.
What happens if I use the Anthropic SDK to call GPT-4o?
Same idea, in reverse: the control plane translates the Anthropic-shape request into OpenAI's wire format on the way out and translates the response back into Anthropic's shape on the way back. Your SDK sees a standard Anthropic response. (Older control plane versions returned 404 for this pair; if you see that, ask your admin to upgrade.)
My framework's retry / fallback fires before VIDAI's fallback chain. Why?
The framework's retry runs in your application; VIDAI's fallback runs server-side. If both are active, the framework wins because it sees the failure first. Disable framework-level retries when you want the control plane to own that behaviour. See Fallback.
Where do I see what the control plane actually sent upstream?
Request Logs → click the request id → expand the upstream-call section. Both the request body the control plane forwarded and the response it received are visible there.
What about embeddings, image generation, audio?
🚧 testcompat coverage pending. Today, OpenAI-shape embeddings and image-gen calls pass through to OpenAI upstreams without translation; the supported-matrix doesn't yet pin the cross-vendor cases. Ask your VIDAI admin if your specific path needs a verification run.
Where to go next¶
- API Keys: minting the key your client
uses for
Authorization: Bearer <key>. - Providers: the upstream side of the picture, covering which provider you've configured, which SDK protocol it speaks, and multi-key rotation.
- Routing: what happens to a call after it lands in the control plane but before it reaches the upstream.
- Fallback: how the control plane recovers when the primary upstream fails. Read this if you're evaluating whether to disable framework-side retries.
- Request Logs: debugging individual calls. The first stop when a client integration misbehaves.