On this page
- Direct-to-provider in one diagram
- A proxy architecture in one diagram
- Privacy changes immediately
- Credential ownership often decides the architecture
- Native and web clients have different constraints
- A proxy can hide provider complexity
- Direct access moves provider integration into the client
- A proxy adds latency, but not always meaningfully
- Streaming proxies must avoid accidental buffering
- Cancellation becomes more complicated through a proxy
- Centralized observability is a major proxy advantage
- Central policy is another major proxy advantage
- Billing works differently
- A proxy can protect provider secrets from untrusted clients
- Direct access can support private-network endpoints
- Proxies create SSRF-style risks when endpoints are user-controlled
- Durable background work often needs a server
- Proxies can normalize provider APIs—but clients can too
- Avoid a “dumb proxy” with no architectural purpose
- Avoid forcing everything direct when the server owns the workflow
- Hybrid architecture example
- Decision matrix
- Architecture checklist
- Where BYOKchat fits
- Further reading
An AI app can reach a model provider in two broad ways:
client → provider
or:
client → application server → provider
The first is direct-to-provider. The second uses a proxy, relay, gateway, or application backend.
Both are legitimate architectures. The mistake is treating the proxy as mandatory infrastructure—or treating direct access as inherently superior—without asking what the product actually needs.
The right choice depends on credentials, platform, privacy, billing, policy, server-side workflows, and operational responsibility.
Direct-to-provider in one diagram
The client owns provider configuration and sends the request itself.
This fits naturally when:
- the user supplies their own provider credential;
- the app is local-first;
- provider usage belongs to the user’s account;
- the platform can reach the provider API directly;
- the app does not need a central server to inspect or transform every request.
A proxy architecture in one diagram
The backend sits in the data path.
It can add value such as:
- app-owned provider credentials;
- central billing and quotas;
- request policy;
- model routing;
- server-side tool execution;
- durable background jobs;
- shared observability;
- webhooks;
- caching or transformation;
- organization-wide controls.
But every request now depends on another system.
Privacy changes immediately
With a direct request:
user content → provider
With a proxy:
user content → app operator → provider
That does not automatically mean the proxy is unsafe. A well-designed server can minimize logs, encrypt transport, enforce retention policy, and provide useful controls.
But it creates another party and infrastructure boundary that can receive the content.
For a local-first BYOK product, avoiding that extra hop can be a meaningful privacy property because the application operator does not need to process prompts and responses at all.
See How Private Is BYOK AI Chat?.
Credential ownership often decides the architecture
If the app operator pays the provider, the client generally should not receive the operator’s secret API key.
That key belongs on trusted server infrastructure:
client authenticates to app
→ app server authenticates to provider
By contrast, a BYOK client may already have a user-owned provider credential stored locally. In that case, sending it directly to the intended provider can be simpler than uploading the credential to an app backend and asking the backend to forward requests.
The question is:
Whose credential is this, and which system actually needs it?
Do not move secrets through extra systems without a reason.
Native and web clients have different constraints
A native iOS or macOS app can usually make HTTPS requests directly to provider endpoints.
A browser application operates under browser security rules such as the same-origin model and CORS. A provider may not permit browser-origin requests in the way your web app requires.
That can force a web product toward:
- a backend proxy;
- a provider-supported browser authentication flow;
- a local companion service;
- another architecture that avoids exposing long-lived keys to page JavaScript.
Therefore:
“direct BYOK works well in a native app”
does not imply:
“put the same API key in localStorage and call the provider from any website.”
Platform threat models matter.
A proxy can hide provider complexity
A server can expose one application API:
POST /v1/chat
while internally routing to several model providers.
The client then does not need to know:
- provider authentication;
- native request schemas;
- provider model IDs;
- retry headers;
- routing policy;
- provider-specific errors.
This is attractive for a hosted product.
But a multi-provider BYOK client often wants provider identity to be visible because the user owns those connections and may choose a specific account/model.
A proxy that hides everything can work against the product model.
Direct access moves provider integration into the client
Without a proxy, the client must implement:
- provider request construction;
- authentication;
- streaming parsing;
- capability handling;
- error classification;
- retries/cancellation;
- model discovery;
- custom endpoint support.
That is real complexity.
The architectural answer is not to scatter provider-specific code across views. Use a provider-adapter layer.
See How a Multi-Provider AI Client Is Architected.
A proxy adds latency, but not always meaningfully
A proxy adds another network leg and another service that must process the stream:
client → backend → provider → backend → client
Potential costs include:
- another DNS/TCP/TLS path;
- buffering mistakes;
- extra serialization;
- proxy cold starts;
- regional distance;
- queueing at the application server.
A well-operated proxy near the user/provider can make the overhead small, and it can even improve effective latency if it manages connections, routing, or caching well.
Do not make blanket performance claims. Measure the actual architecture.
Streaming proxies must avoid accidental buffering
An AI response may arrive token by token or event by event.
A proxy must relay that incrementally. If the server, framework, CDN, or reverse proxy buffers the upstream response, the client can see behavior like:
provider streams for 8 seconds
backend buffers everything
client receives one big chunk at second 8
The API technically “works” but the product loses streaming UX.
A proxy path must be tested end-to-end for:
- first-byte latency;
- chunk/event forwarding;
- cancellation propagation;
- idle timeouts;
- backpressure;
- disconnect behavior.
Cancellation becomes more complicated through a proxy
Direct:
client cancels provider request
Proxy:
client disconnects
→ backend notices
→ backend cancels upstream provider request
If the backend ignores the client disconnect, provider generation may continue after the user presses Stop.
That can waste usage and create confusing state.
Cancellation needs to propagate through every hop.
Centralized observability is a major proxy advantage
A backend can observe requests across all users and providers:
request rate
TTFT
duration
error rate
retry rate
model/provider health
cost/account usage
That is valuable for operating a hosted product.
A direct local-first app does not naturally give the operator that visibility, which can be a feature for privacy but a challenge for support.
A direct client can still maintain local sanitized telemetry without transmitting prompts or secrets.
The tradeoff is intentional:
central observability
vs
minimal operator visibility
Central policy is another major proxy advantage
A backend can enforce:
- approved models;
- organization quotas;
- content policy;
- rate limits;
- tool allowlists;
- routing rules;
- account-level spending limits;
- audit requirements.
That is useful for enterprise or hosted products.
In a personal BYOK client, policy may instead be local and user-controlled.
Neither is intrinsically more secure. Security depends on whose authority the product is supposed to enforce.
Billing works differently
A proxy with app-owned keys allows the app operator to meter and resell inference:
user pays app
app pays provider
Direct BYOK usually looks like:
user pays provider
user may separately pay for client software/features
These are different business models, not merely network topologies.
See API Key vs AI Subscription.
A proxy can protect provider secrets from untrusted clients
If a service owns one shared provider key, that secret must never ship inside a public app binary or browser bundle.
A backend proxy is the normal boundary:
public client knows app auth
trusted server knows provider secret
This is one of the strongest reasons to use a proxy for hosted inference.
By contrast, in BYOK the credential belongs to the user and is expected to exist on their device.
Do not confuse app-owned provider secrets with user-owned BYOK credentials.
Direct access can support private-network endpoints
A native client may reach resources unavailable to a public backend:
192.168.x.x
10.x.x.x
localhost-equivalent services on another LAN machine
private VPN addresses
This matters for local AI servers.
A cloud proxy usually cannot reach a user’s private LAN endpoint—and should not try to tunnel arbitrary private addresses without a carefully designed security model.
Direct native networking is therefore a natural fit for local OpenAI-compatible servers.
See How to Connect a Local OpenAI-Compatible Server to iPhone.
Proxies create SSRF-style risks when endpoints are user-controlled
If your backend accepts:
{
"base_url": "http://user-supplied-host"
}
and fetches it server-side, users may attempt to make your infrastructure access internal services, metadata endpoints, or other restricted resources.
That is a classic reason to be cautious with server-side fetching of arbitrary BYOK endpoints.
A native client connecting to the user’s own private network has a different trust boundary.
Durable background work often needs a server
Direct client execution is excellent while the app is running.
But some features need to outlive the client:
- long-running jobs;
- scheduled work;
- webhook processing;
- server-to-server integrations;
- shared organization workflows;
- notifications after the app closes.
Those features may justify backend infrastructure even if ordinary chat remains direct-to-provider.
A hybrid architecture can keep interactive chat direct while using a server only for durable workflows.
See How Long-Running AI Tasks Work.
Proxies can normalize provider APIs—but clients can too
It is tempting to say:
multi-provider → must use one server gateway
That is not true.
Normalization can happen in either place:
client-side provider adapters
or:
server-side provider adapters
The location should follow the product’s execution and trust model.
A native BYOK client can normalize providers locally and keep the provider relationship under user control.
Avoid a “dumb proxy” with no architectural purpose
A particularly weak design is:
client sends prompt + user's provider key to your server
server forwards both unchanged
server forwards response unchanged
This adds:
- another privacy boundary;
- another outage point;
- another credential-processing system;
- extra infrastructure;
- potential latency;
without adding much product value.
There are situations where even a thin relay is required—for browser constraints, network policy, or observability—but the reason should be explicit.
Avoid forcing everything direct when the server owns the workflow
The opposite mistake is architectural purity around direct calls.
If the backend is already responsible for:
workflow state
scheduled execution
tool credentials
webhooks
team policy
shared audit log
then server-side model execution may be the coherent design.
Do not bounce a server-owned operation back to a mobile client merely to preserve the phrase “direct-to-provider.”
Hybrid architecture example
Different features can have different execution paths.
The important part is making those paths understandable and auditable.
Decision matrix
| Requirement | Direct-to-provider | Proxy/backend |
|---|---|---|
| User-owned API key | Strong fit | Possible but adds secret handling |
| App-owned provider key | Poor fit | Strong fit |
| Local/private endpoint | Strong native fit | Usually poor fit |
| Central billing | Weak fit | Strong fit |
| Minimal operator access to prompts | Strong fit | Requires server privacy design |
| Organization policy | Local only | Strong centralized fit |
| Background jobs after client closes | Limited | Strong fit |
| Browser CORS constraints | Sometimes difficult | Often useful |
| Central model routing | Client-side possible | Natural fit |
| Offline-readable local history | Natural | Independent of execution path |
Architecture checklist
Before adding or removing a proxy, ask:
- who owns the provider credential?
- who pays provider usage?
- does the server need to inspect the request?
- does a workflow need to outlive the client?
- are endpoints user-controlled or private-network addresses?
- does the platform support direct provider networking?
- what privacy promise does the product make?
- where should policy be enforced?
- who needs observability?
- how does cancellation propagate?
- can streaming remain truly incremental?
- what new outage/security boundary does the proxy create?
Where BYOKchat fits
BYOKchat is designed around direct provider-native communication for interactive chat because users own their provider connections and local conversation data. That keeps ordinary prompts out of an unnecessary application relay and allows private-network compatible endpoints to work from the device.
The broader principle is more important than any one product: use a backend when it provides a real capability, not merely because an AI request exists.