Responses Proxy provider registration
Register providers through the Responses dashboard/BFF or through the authenticated /admin/* API. The browser should never send provider secrets directly to the backend service; the frontend BFF injects the admin bearer server-side.
For direct operator API calls:
export RESPONSES_PROXY_BASE_URL="https://agent-responses-proxy.svc.cloud.morph.so"
export ADMIN_HEADER="Authorization: Bearer $PROXY_ADMIN_TOKEN"
Validate before saving
Use presets to populate provider forms:
curl -sS -H "$ADMIN_HEADER" "$RESPONSES_PROXY_BASE_URL/admin/provider-presets"
Validate unsaved provider settings:
curl -sS -X POST "$RESPONSES_PROXY_BASE_URL/admin/providers/test" \
-H "$ADMIN_HEADER" \
-H "content-type: application/json" \
-d '{
"id": "kimi-main",
"name": "Kimi Main",
"provider_type": "custom",
"base_url": "https://api.moonshot.ai/v1",
"wire_api": "chat_completions",
"auth_type": "bearer",
"api_key": "replace-with-provider-key"
}'
After saving a provider, validate an upstream model id:
curl -sS -X POST "$RESPONSES_PROXY_BASE_URL/admin/models/test" \
-H "$ADMIN_HEADER" \
-H "content-type: application/json" \
-d '{"provider_id":"kimi-main","upstream_id":"kimi-k2.6"}'
OpenAI Responses
Register an OpenAI Responses provider:
curl -sS -X POST "$RESPONSES_PROXY_BASE_URL/admin/providers" \
-H "$ADMIN_HEADER" \
-H "content-type: application/json" \
-d '{
"id": "openai-main",
"name": "OpenAI Main",
"provider_type": "openai",
"base_url": "https://api.openai.com/v1",
"wire_api": "responses",
"auth_type": "bearer",
"api_key": "replace-with-provider-key"
}'
Register a client-facing alias:
curl -sS -X POST "$RESPONSES_PROXY_BASE_URL/admin/models" \
-H "$ADMIN_HEADER" \
-H "content-type: application/json" \
-d '{
"alias": "openai/gpt-mini",
"provider_id": "openai-main",
"upstream_id": "gpt-4.1-mini"
}'
Clients then send:
{"model": "openai/gpt-mini", "input": "hello"}
Kimi and OpenAI-compatible Chat
Kimi, OpenRouter, and many gateways use the OpenAI-compatible Chat Completions protocol.
curl -sS -X POST "$RESPONSES_PROXY_BASE_URL/admin/providers" \
-H "$ADMIN_HEADER" \
-H "content-type: application/json" \
-d '{
"id": "kimi-main",
"name": "Kimi Main",
"provider_type": "custom",
"base_url": "https://api.moonshot.ai/v1",
"wire_api": "chat_completions",
"auth_type": "bearer",
"api_key": "replace-with-provider-key",
"config": {"endpoint_path": "chat/completions"}
}'
Register an alias:
curl -sS -X POST "$RESPONSES_PROXY_BASE_URL/admin/models" \
-H "$ADMIN_HEADER" \
-H "content-type: application/json" \
-d '{"alias":"kimi/k2","provider_id":"kimi-main","upstream_id":"kimi-k2.6"}'
For OpenRouter, use its base URL and upstream model id:
{
"id": "openrouter-main",
"base_url": "https://openrouter.ai/api/v1",
"wire_api": "chat_completions",
"upstream_id_example": "replace-with-openrouter-model-id"
}
Anthropic Messages
Anthropic uses the Messages API with an API-key header:
curl -sS -X POST "$RESPONSES_PROXY_BASE_URL/admin/providers" \
-H "$ADMIN_HEADER" \
-H "content-type: application/json" \
-d '{
"id": "anthropic-main",
"name": "Anthropic Main",
"provider_type": "anthropic",
"base_url": "https://api.anthropic.com/v1",
"wire_api": "anthropic_messages",
"auth_type": "api_key",
"auth_header": "x-api-key",
"health_path": null,
"api_key": "replace-with-provider-key",
"config": {
"endpoint_path": "messages",
"anthropic_version": "2023-06-01",
"default_max_tokens": 4096
}
}'
Register an alias:
curl -sS -X POST "$RESPONSES_PROXY_BASE_URL/admin/models" \
-H "$ADMIN_HEADER" \
-H "content-type: application/json" \
-d '{
"alias": "anthropic/sonnet",
"provider_id": "anthropic-main",
"upstream_id": "replace-with-anthropic-model-id"
}'
Use aliases from Codex
Codex still points at Responses Proxy as a Responses provider. Choose a registered alias as the model:
codex \
-c model_provider='"proxy"' \
-c model='"kimi/k2"' \
-c model_providers.proxy.name='"Responses Proxy"' \
-c model_providers.proxy.base_url='"https://agent-responses-proxy.svc.cloud.morph.so/v1"' \
-c model_providers.proxy.wire_api='"responses"'
For aliases Codex does not know, add them to codex-model-catalog.json or provide your own catalog with MODEL_CATALOG_JSON=/path/to/models.json.
Current limits
responses,chat_completions, andanthropic_messagesproviders are routable.wire_api="custom"providers are stored but not routable until a custom adapter exists.- Non-Responses adapters support text, streaming text, function tools, Codex custom tools, and namespace tool containers.
- OpenAI-hosted Responses tools that cannot run on Chat Completions or Anthropic providers, such as
web_search, are omitted for compatibility. - Image, audio, realtime, and unknown provider-specific tool types fail early with a clear error.
- Chat Completions and Anthropic are stateless upstream protocols, so the proxy stores reconstructed response state in SQL for
previous_response_idcontinuations.