Drop-in proxy¶
The proxy records each AI call and forwards it to the real provider, so you get
request-level attribution without touching application logic. You change one
thing: the provider SDK’s base URL. Substitute the <your-venturi-instance>
placeholder below by the base-URL rule: https:// on the SaaS
tier, or your own instance host when self-hosted (see
Deployment modes).
Fail-open guarantee
The proxy runs Venturi’s decision-time interceptor: a fast index lookup with a 50 ms P99 end-to-end budget (15 ms internal), enforced by a cooperative timeout against a cumulative deadline. If the lookup, the event stream, or any other Venturi dependency behind the proxy is slow, degraded, or unavailable, the request is forwarded to the provider unmodified. A slow or unavailable Venturi dependency never blocks or fails a proxied request. The one deliberate rejection is tenant admission, which fails closed: a provider key that is not registered to your tenant is rejected before anything is forwarded.
The proxy endpoint itself is on your request path
Fail-open covers the Venturi dependencies behind the proxy, not the proxy
endpoint itself. When your SDK’s base URL points at the proxy, a request
reaches the provider only if it first reaches the proxy: on the SaaS tier
that is the shared api.venturi.systems host, and in self-hosted mode it
is your own instance host. The serving-availability objective and support-tier
commitments on SLAs & SLOs cover the
dashboard, query API, and exports, not the proxy endpoint. For a workload
that cannot accept that dependency, configure client-side failover that
sends the request to the provider’s direct base URL when the proxy endpoint
cannot be reached (calls that fail over carry no proxy capture), or capture
the workload through the Ingestion API or a
cloud connection, which do not route your AI
requests through Venturi.
How it works¶
- Your app sends the AI request to the Venturi proxy using the proxy
base_url. - The proxy forwards the request unchanged to OpenAI, Anthropic, or Amazon Bedrock, then returns the provider response to your app.
- The proxy emits a metadata-only
InvocationEventto the attribution pipeline.
The proxy passes your request through unchanged (including your provider API key,
which Venturi does not store), captures metadata (model, tokens, latency, cost)
and emits an InvocationEvent. Request and response content exists only in
memory while being forwarded and is never written to access logs, error logs,
traces, queues, or exception payloads, including on error and timeout paths.
Tenant admission¶
The proxy binds each call to your tenant from server-side state, never from a client-supplied header: a tenant header you send is stripped and never becomes the event’s tenant. The binding comes from the provider API key the call carries. Each provider key you route through the proxy is registered to your tenant as a one-way fingerprint, never as the key itself, and on the shared SaaS hostname that fingerprint is also what routes the call to your dedicated data plane.
| Situation | Outcome |
|---|---|
| The key is registered to your tenant | Admitted. The fail-open guarantee applies from here on. |
| The call carries no provider key | Rejected 401 before anything is forwarded. |
| The key is not registered to an active tenant, such as a new or rotated key you have not registered yet | Rejected 403 before anything is forwarded. |
| The lookup that resolves the key cannot answer in time | Forwarded unmodified under the fail-open rule, with null attribution. |
Register every provider key under Settings / Admin / Credentials before you send traffic with it, including each new or rotated key. Venturi reduces the key to its fingerprint at registration and does not retain the key itself. During a rotation, register the new key first, move traffic to it, and remove the old key once no traffic uses it.
Endpoints¶
Set your SDK’s base URL to the value for your provider, relative to your Venturi instance host:
| Provider | SDK base URL path | Provider paths it serves |
|---|---|---|
| OpenAI | / |
/chat/completions and other OpenAI API paths |
| Anthropic | / |
/v1/messages |
| Amazon Bedrock | / |
Bedrock Runtime paths such as / |
The OpenAI SDK appends paths such as /chat/completions to its base URL, so the
OpenAI base URL ends in /v1. The Anthropic SDK appends /v1/messages itself, so
the Anthropic base URL stops at /anthropic.
OpenAI example¶
Anthropic example¶
from anthropic import Anthropic
client = Anthropic(
base_url="https://<your-venturi-instance>/api/v1/proxy/anthropic",
api_key="<your Anthropic key>", # forwarded as-is; not stored by Venturi
)
client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
Amazon Bedrock example¶
Authenticate Bedrock calls through the proxy with a long-term
Amazon Bedrock API key
in the Authorization: Bearer header, registered to your tenant like any other
provider key (see Tenant admission). The proxy forwards that
header unchanged and does not re-sign requests, so AWS Signature Version 4
credentials, which are bound to the host they were signed for, do not work
through the proxy. Requests go to the Bedrock Runtime regional endpoint
configured for your instance during onboarding.
Short-term Bedrock API keys are not admitted: each one expires within 12 hours
and cannot be registered in advance. AWS recommends short-term keys for
production and long-term keys for exploration, so for production Bedrock
workloads that use short-term keys or Signature Version 4, capture usage through
the AWS cloud connection, which reads Bedrock invocation
metadata, or emit events from your code through the Ingestion API.
When you rotate a long-term key, for example with the IAM
ResetServiceSpecificCredential action, register the new value before you move
traffic to it.
curl -X POST "https://<your-venturi-instance>/api/v1/proxy/bedrock/model/us.anthropic.claude-sonnet-4-6/converse" \
-H "Authorization: Bearer $AWS_BEARER_TOKEN_BEDROCK" \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":[{"text":"Hello"}]}]}'
The us. prefix in us. names a US geographic
cross-Region inference profile. Use the profile ID whose geography prefix
matches the Bedrock Region configured for your instance. For this model those
are us., eu., jp., and au., or global. for global cross-Region
inference. The
Claude Sonnet 4.6 model card
lists the exact profile IDs and the source Regions each one serves; for other
models, see
Supported Regions and models for inference profiles.
Attributing the call¶
To attribute a call beyond “this API key”, add attribution headers to the
request. The proxy records their values as metadata on the call’s
InvocationEvent and removes them before it forwards the request, so the
provider never receives them:
The last column gives the equivalent Ingestion API field.
| Header | Declares | API field |
|---|---|---|
X-Venturi-User |
The identity that made the call | attributed_identity |
X-Venturi-Service |
The service that made the call | attributed_service |
X-Venturi-Team |
The owning team, used as a direct team match | None |
X-Venturi-Cost-Center |
The cost center to attribute the call to | None |
Each value is an explicit declaration by the calling workload, so keep it to an identifier, never message content. A tenant header is not one of these: the proxy strips any tenant header you send and binds the call to your tenant from the provider key (see Tenant admission).
Streaming¶
OpenAI and Anthropic Server-Sent Events are forwarded incrementally, and token
counts are derived from the stream. Amazon Bedrock binary event streams
(ConverseStream and InvokeModelWithResponseStream) are forwarded frame by
frame; the proxy parses the event-stream frames for the token counts Bedrock
reports and preserves Bedrock’s token-count headers.
Sign in to send feedback. Opens in a new tab.
Copy page details
Docs feedback: Drop-in proxy
Page: https://docs.venturi.systems/ingestion/proxy/