APIZDocs

APIZ guide

OpenAI API

Use adapter ID openai for a provider that speaks the native OpenAI-compatible API. APIZ preserves the protocol and model name. Support for one endpoint does not imply support for every OpenAI feature.

What This Adapter Supports

Logical endpointActionPurpose
POST /v1/chat/completionsopenai:chat_completions:createNative JSON or SSE generation
POST /v1/responsesopenai:responses:createStateless native JSON or SSE generation
GET /v1/modelsopenai:models:listModel discovery
GET /v1/models/{model}openai:models:retrieveOne model's metadata

New root-only connections expose the adapter's supported native routes. This is not a guarantee that the upstream implements each route. Client-executed function tools and provider extensions pass through without protocol conversion. Previously saved provider defaults and endpoint restrictions remain enforced; new operation restrictions belong in Policy.

The complete upstream API root belongs in http.base_url. The default is https://api.openai.com/v1; for DeepSeek use https://api.deepseek.com. A custom root such as https://llm.example.invalid/api/v1 receives /chat/completions appended to it. Do not include /chat/completions in the configured root. HTTPS is supported; HTTP is restricted to loopback for local development.

Credential Boundary

Store the upstream API key in the write-only credential field. The agent receives a different APIZ Temporary Credential, normally prefixed sk-apiz-. APIZ validates the Client, Binding, request, and optional Policies before the Secret Broker releases upstream credential material. Caller authentication, cookies, and project/organization overrides are removed before forwarding.

auth_mode:none is an explicit option for an unauthenticated local server. It does not disable APIZ authentication. Do not put an upstream key in the API root, label, tags, Policy, or agent environment.

Prepare The Upstream Credential

Create a provider API key with the project and spending controls appropriate for the workload. Keep its value on the trusted management side. For a local Qwen server without authentication, use the explicit CLI configuration below.

Consult the provider's OpenAI API documentation or DeepSeek API documentation for its own models and capabilities. Each provider and account needs separate capability validation.

Web Console

  1. Open API Instances → Create API Instance → OpenAI API.
  2. Enter a name and review the prefilled API root; replace it for another provider.
  3. Enter the write-only API key. The adapter handles upstream authentication.
  4. Optionally attach a model or operation Policy. Run the connection test and save. The result covers only model discovery (OpenAI) or token counting (Anthropic), not generation or all provider capabilities. A provider without that diagnostic endpoint can still be tested with an explicit, bounded generation request; that request may incur provider charges.

CLI

Run these commands in Bash on the trusted management machine:

apiz adapter explain openai
read -rsp "Upstream API key: " LLM_API_KEY && printf '\n'
printf '%s' "$LLM_API_KEY" | jq -Rs '{credential: .}' |
apiz -o json api create \
  --adapter openai --name team-llm \
  --config-json '{"http":{"base_url":"https://api.deepseek.com"}}' \
  --credential-stdin
unset LLM_API_KEY

For a local server:

apiz -o json api create --adapter openai --name local-qwen \
  --config-json '{"provider":"custom","auth_mode":"none","http":{"base_url":"http://127.0.0.1:18081/v1"}}'

The loopback address is relative to the APIZ backend process. A server running on your laptop is not reachable through a remote deployment's loopback address.

Give An Agent Access

apiz -o json client create --name llm-agent
apiz client bind <client-id> --api-instance <api-instance-id> --alias llm
apiz client credentials create <client-id> --binding llm --ttl 1h --format json

The Web flow is Clients → Add Binding → Create Temporary Credentials. Use the LLM item in the Setup Manifest. Its endpoint is the APIZ binding root and its auth.credential is the Temporary Credential. Set SDK base_url to that endpoint with /v1 appended. The sdk-args format already emits native base_url and api_key arguments. Bind a model Policy when the upstream key can access models the agent should not use.

Select Shell Session or dotenv to receive OPENAI_BASE_URL and OPENAI_API_KEY for the selected connection. These use the APIZ endpoint and temporary binding key, never the upstream provider key. Shell/dotenv also retain APIZ CLI bootstrap configuration and namespaced binding variables. The bootstrap token can recover the entire issued Credential Group. Select one OpenAI-compatible item at a time; multiple items cannot share the same native environment variables. Unselected services, including S3, do not contribute configuration.

Use It From The Agent

Set APIZ_LLM_ENDPOINT and APIZ_TEMPORARY_CREDENTIAL from the Setup Manifest. A read-only discovery request is:

curl -fsS -H "Authorization: Bearer $APIZ_TEMPORARY_CREDENTIAL" \
  "$APIZ_LLM_ENDPOINT/v1/models"

With the official Python openai package installed:

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.environ["APIZ_LLM_ENDPOINT"].rstrip("/") + "/v1",
    api_key=os.environ["APIZ_TEMPORARY_CREDENTIAL"],
)
result = client.chat.completions.create(
    model=os.environ["LLM_MODEL"],
    messages=[{"role": "user", "content": "Say hello briefly."}],
    max_tokens=32,
)
print(result.choices[0].message.content)

Choose an output-limit parameter supported by the model: Chat Completions accepts either max_tokens or max_completion_tokens, never both. Generation may incur provider charges. Responses uses max_output_tokens and requires explicit store=False; send conversation context as inline input.

Policy Actions And Resources

The resource has type:llm_model, endpoint, and the exact model ID. Generation also exposes stream, tool_count, and an optional max_output_tokens, normalized from the native parameter. Model listing has no model ID. Prompts, tool arguments, and generated text are excluded.

The optional Allow one LLM model template denies model listing because it has no model ID. Adjust your Policy deliberately if discovery is needed. To require a bounded request, a scripted Policy can check:

if (ctx.resource.model !== "example-model") return api.deny("model_not_allowed");
if (!Number.isSafeInteger(ctx.resource.max_output_tokens) ||
    ctx.resource.max_output_tokens > 256) return api.deny("output_limit_required");
return api.allow("bounded_model_request");

Replace the model ID before binding. An output limit is a per-request protocol parameter, not a monetary budget or a guarantee about provider billing.

Connection Tests

The default test reads /v1/models and requires HTTP 200 with a JSON model list. An optional model target retrieves that model's metadata. Neither test generates text or creates persistent resources. The models endpoint must be enabled.

A successful test establishes discovery and authentication for that request. It does not prove tool calling, Responses, streaming, model availability for generation, or compatibility with every SDK option.

Evidence And Troubleshooting

Use request evidence to distinguish APIZ authentication, Policy denial, Secret Broker failure, and an upstream response. A provider HTTP 200 can still contain a protocol error. The bounded observer reports complete, failed, incomplete, or unknown and safe cumulative usage counters when present. unknown can mean unsupported framing or observation size limits; the proxy still forwards the original bytes.

  • unsupported_openai_endpoint: inspect the method, logical path, enabled endpoints, and unsupported query parameters.
  • Provider validation errors: check the selected provider's support for the submitted content, tools, and state options.
  • invalid_openai_output_limit: use a positive integer and the native parameter for the selected endpoint.
  • Discovery succeeds but generation fails: check the provider's model, API permissions, billing, and requested feature support.
  • An upstream 404 often indicates that the configured root includes an extra operation or is missing the provider's version prefix.

Current Limitations

There is no Anthropic translation, model aliasing, provider failover, automatic retry after streaming begins, token billing, OAuth, Azure deployment routing, Realtime, file-management endpoints, batches, embeddings, or persistent response CRUD. State references, storage/background options, and tool definitions within supported generation requests pass through for the provider to validate. Legacy functions/function_call remain unsupported; use native tools.

APIZ does not provide per-Client isolation of upstream account resources or hosted tool permissions. Clients sharing an upstream credential share its provider-side permissions, including access to files and conversations. Use separate upstream credentials/accounts when that isolation is required. Passing a field through does not establish provider support for it.

Generation JSON is bounded by the platform body ceiling (default 1 MiB, hard maximum 8 MiB), with unique keys and nesting limited to 64 levels. Observation is bounded to 64 KiB per SSE event and 1 MiB for a JSON response. Multimodal inline inputs may exceed those bounds. Unknown provider fields pass through; provider-specific semantics need separate compatibility testing.