ai-proxy
The ai-proxy plugin forwards LLM and embedding requests to OpenAI, DeepSeek, Anthropic, Gemini, Vertex AI, and other compatible providers. A common plugin configuration applies the provider-specific authentication, endpoint, and request format.
Before forwarding a request, the plugin identifies the client protocol from the request URI and body. Protocol conversion applies when the client uses Anthropic Messages but the selected provider supports OpenAI Chat Completions instead of native Anthropic Messages. The plugin converts the client request to OpenAI format and the backend response to Anthropic format. This conversion supports only a subset of Anthropic Messages. See Protocol Reference for detection rules, field mappings, release boundaries, and limitations.
The plugin can also record LLM request information in the access log, not the error log, including token usage, model, and time to first response. Logging plugins can consume these entries.
Examples
The following examples configure ai-proxy for common provider and protocol scenarios.
Proxy to OpenAI
The following example configures ai-proxy on a route that sends chat requests to OpenAI.
Obtain an OpenAI API key and optionally save it to an environment variable:
export OPENAI_API_KEY="<OPENAI_API_KEY>"
- Admin API
- ADC
- Ingress Controller
Create a route with the ai-proxy plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d @- <<EOF
{
"id": "ai-proxy-route",
"uri": "/anything",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer $OPENAI_API_KEY"
}
},
"options":{
"model": "gpt-4.1-mini"
}
}
}
}
EOF
❶ Specify the provider to be openai.
❷ Attach OpenAI API key in the Authorization header.
❸ Specify the name of the model.
Create a route with the ai-proxy plugin:
services:
- name: openai-service
labels:
docs-example: ai-proxy-openai
routes:
- name: openai-route
uris:
- /anything
methods:
- POST
plugins:
ai-proxy:
provider: openai
auth:
header:
Authorization: Bearer ${OPENAI_API_KEY}
options:
model: gpt-4.1-mini
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Review the diff for unexpected changes or deletions before syncing these services:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-openai
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-openai
❶ Specify the provider to be openai.
❷ Attach OpenAI API key in the Authorization header.
❸ Specify the name of the model.
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-proxy-plugin-config
spec:
plugins:
- name: ai-proxy
config:
provider: openai
auth:
header:
Authorization: "Bearer <OPENAI_API_KEY>"
options:
model: gpt-4.1-mini
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: openai-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-proxy-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
Apply the configuration to your cluster:
kubectl apply -f ai-proxy-ic.yaml
❶ Specify the provider to be openai.
❷ Attach OpenAI API key in the Authorization header.
❸ Specify the name of the model.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: openai-route
spec:
ingressClassName: apisix
http:
- name: openai-route
match:
paths:
- /anything
methods:
- POST
plugins:
- name: ai-proxy
enable: true
config:
provider: openai
auth:
header:
Authorization: "Bearer <OPENAI_API_KEY>"
options:
model: gpt-4.1-mini
Apply the configuration to your cluster:
kubectl apply -f ai-proxy-ic.yaml
❶ Specify the provider to be openai.
❷ Attach OpenAI API key in the Authorization header.
❸ Specify the name of the model.
The ADC and Gateway API tabs include a conventional backend. When the plugin handles the request itself, the backend is not contacted. Verify the plugin-specific result below; a backend response alone does not confirm that the plugin ran.
Send a POST request to the route with a system prompt and a sample user question in the request body:
curl "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "You are a mathematician" },
{ "role": "user", "content": "What is 1+1?" }
]
}'
You should receive a response similar to the following:
{
...,
"model": "gpt-4.1-mini-2025-04-14",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "1+1 equals 2.",
"refusal": null
},
"logprobs": null,
"finish_reason": "stop"
}
],
...
}
If the LLM upstream returns 429 or a 5xx response, the client receives the upstream status, response body, and Content-Type. This preserves any provider error details.
Proxy to DeepSeek
The following example configures ai-proxy to send chat requests to DeepSeek.
Obtain the DeepSeek API key and optionally save it to an environment variable:
export DEEPSEEK_API_KEY="<DEEPSEEK_API_KEY>"
- Admin API
- ADC
- Ingress Controller
Create a route with the ai-proxy plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d @- <<EOF
{
"id": "ai-proxy-route",
"uri": "/anything",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "deepseek",
"auth": {
"header": {
"Authorization": "Bearer $DEEPSEEK_API_KEY"
}
},
"options": {
"model": "deepseek-chat"
}
}
}
}
EOF
❶ Specify the provider to be deepseek, so that the plugin will proxy requests to https://api.deepseek.com/chat/completions.
❷ Attach DeepSeek API key in the Authorization header.
❸ Specify the name of the model.
Create a route with the ai-proxy plugin:
services:
- name: deepseek-service
labels:
docs-example: ai-proxy-deepseek
routes:
- name: deepseek-route
uris:
- /anything
methods:
- POST
plugins:
ai-proxy:
provider: deepseek
auth:
header:
Authorization: Bearer ${DEEPSEEK_API_KEY}
options:
model: deepseek-chat
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Review the diff for unexpected changes or deletions before syncing these services:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-deepseek
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-deepseek
❶ Specify the provider to be deepseek, so that the plugin will proxy requests to https://api.deepseek.com/chat/completions.
❷ Attach DeepSeek API key in the Authorization header.
❸ Specify the name of the model.
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-proxy-plugin-config
spec:
plugins:
- name: ai-proxy
config:
provider: deepseek
auth:
header:
Authorization: "Bearer <DEEPSEEK_API_KEY>"
options:
model: deepseek-chat
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: deepseek-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-proxy-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
Apply the configuration to your cluster:
kubectl apply -f deepseek-ic.yaml
❶ Specify the provider to be deepseek, so that the plugin will proxy requests to https://api.deepseek.com/chat/completions.
❷ Attach DeepSeek API key in the Authorization header.
❸ Specify the name of the model.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: deepseek-route
spec:
ingressClassName: apisix
http:
- name: deepseek-route
match:
paths:
- /anything
methods:
- POST
plugins:
- name: ai-proxy
enable: true
config:
provider: deepseek
auth:
header:
Authorization: "Bearer <DEEPSEEK_API_KEY>"
options:
model: deepseek-chat
Apply the configuration to your cluster:
kubectl apply -f deepseek-ic.yaml
❶ Specify the provider to be deepseek, so that the plugin will proxy requests to https://api.deepseek.com/chat/completions.
❷ Attach DeepSeek API key in the Authorization header.
❸ Specify the name of the model.
Send a POST request to the route with a sample question in the request body:
curl "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "system",
"content": "You are an AI assistant that helps people find information."
},
{
"role": "user",
"content": "Write me a 50-word introduction for Apache APISIX."
}
]
}'
You should receive a response similar to the following:
{
...
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Apache APISIX is a dynamic, real-time, high-performance API gateway and cloud-native platform. It provides rich traffic management features like load balancing, dynamic upstream, canary release, circuit breaking, authentication, observability, and more. Designed for microservices and serverless architectures, APISIX ensures scalability, security, and seamless integration with modern DevOps workflows."
},
"logprobs": null,
"finish_reason": "stop"
}
],
...
}
Proxy to Azure OpenAI
The following example sends Chat Completions requests to an Azure OpenAI deployment through its v1 API.
Obtain the Azure OpenAI API key and optionally save it to an environment variable:
export AZ_OPENAI_API_KEY="<AZURE_OPENAI_API_KEY>"
- Admin API
- ADC
- Ingress Controller
Create a route with the ai-proxy plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d @- <<EOF
{
"id": "ai-proxy-route",
"uri": "/anything",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai-compatible",
"auth": {
"header": {
"api-key": "$AZ_OPENAI_API_KEY"
}
},
"options":{
"model": "<AZURE_OPENAI_DEPLOYMENT>"
},
"override": {
"endpoint": "https://<AZURE_OPENAI_RESOURCE>.openai.azure.com/openai/v1/chat/completions"
}
}
}
}
EOF
❶ Set the provider to openai-compatible so the deployment name remains in the v1 request body.
❷ Attach Azure OpenAI API key in the api-key header.
❸ Specify the Azure OpenAI deployment name.
❹ Specify the Azure OpenAI v1 Chat Completions endpoint.
Create a route with the ai-proxy plugin:
services:
- name: azure-openai-service
labels:
docs-example: ai-proxy-azure-openai
routes:
- name: azure-openai-route
uris:
- /anything
methods:
- POST
plugins:
ai-proxy:
provider: openai-compatible
auth:
header:
api-key: ${AZ_OPENAI_API_KEY}
options:
model: <AZURE_OPENAI_DEPLOYMENT>
override:
endpoint: "https://<AZURE_OPENAI_RESOURCE>.openai.azure.com/openai/v1/chat/completions"
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Review the diff for unexpected changes or deletions before syncing these services:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-azure-openai
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-azure-openai
❶ Set the provider to openai-compatible so the deployment name remains in the v1 request body.
❷ Attach Azure OpenAI API key in the api-key header.
❸ Specify the Azure OpenAI deployment name.
❹ Specify the Azure OpenAI v1 Chat Completions endpoint.
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-proxy-plugin-config
spec:
plugins:
- name: ai-proxy
config:
provider: openai-compatible
auth:
header:
api-key: "<AZURE_OPENAI_API_KEY>"
options:
model: <AZURE_OPENAI_DEPLOYMENT>
override:
endpoint: "https://<AZURE_OPENAI_RESOURCE>.openai.azure.com/openai/v1/chat/completions"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: azure-openai-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-proxy-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
Apply the configuration to your cluster:
kubectl apply -f azure-openai-ic.yaml
❶ Set the provider to openai-compatible so the deployment name remains in the v1 request body.
❷ Attach Azure OpenAI API key in the api-key header.
❸ Specify the Azure OpenAI deployment name.
❹ Specify the Azure OpenAI v1 Chat Completions endpoint.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: azure-openai-route
spec:
ingressClassName: apisix
http:
- name: azure-openai-route
match:
paths:
- /anything
methods:
- POST
plugins:
- name: ai-proxy
enable: true
config:
provider: openai-compatible
auth:
header:
api-key: "<AZURE_OPENAI_API_KEY>"
options:
model: <AZURE_OPENAI_DEPLOYMENT>
override:
endpoint: "https://<AZURE_OPENAI_RESOURCE>.openai.azure.com/openai/v1/chat/completions"
Apply the configuration to your cluster:
kubectl apply -f azure-openai-ic.yaml
❶ Set the provider to openai-compatible so the deployment name remains in the v1 request body.
❷ Attach Azure OpenAI API key in the api-key header.
❸ Specify the Azure OpenAI deployment name.
❹ Specify the Azure OpenAI v1 Chat Completions endpoint.
Send a POST request to the route with a sample question in the request body:
curl "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "system",
"content": "You are an AI assistant that helps people find information."
},
{
"role": "user",
"content": "Write me a 50-word introduction for Apache APISIX."
}
],
"max_tokens": 800,
"temperature": 0.7,
"frequency_penalty": 0,
"presence_penalty": 0,
"top_p": 0.95,
"stop": null
}'
You should receive a response similar to the following:
{
"choices": [
{
...,
"message": {
"content": "Apache APISIX is a modern, cloud-native API gateway built to handle high-performance and low-latency use cases. It offers a wide range of features, including load balancing, rate limiting, authentication, and dynamic routing, making it an ideal choice for microservices and cloud-native architectures.",
"role": "assistant"
}
}
],
...
}
Proxy to Gemini
The following example sends chat requests to the Gemini API. Gemini support was introduced in API7 Enterprise 3.9.2 and APISIX 3.15.0.
Obtain a Gemini API key and optionally save it to an environment variable:
export GEMINI_API_KEY="<GEMINI_API_KEY>"
- Admin API
- ADC
- Ingress Controller
Create a route with the ai-proxy plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d @- <<EOF
{
"id": "ai-proxy-gemini-route",
"uri": "/anything",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "gemini",
"auth": {
"header": {
"Authorization": "Bearer $GEMINI_API_KEY"
}
},
"options": {
"model": "gemini-3.5-flash"
}
}
}
}
EOF
❶ Specify the provider to be gemini.
❷ Replace with your Gemini API key in the Authorization header.
❸ Specify the name of the Gemini model.
Create a route with the ai-proxy plugin:
services:
- name: gemini-service
labels:
docs-example: ai-proxy-gemini
routes:
- name: gemini-route
uris:
- /anything
methods:
- POST
plugins:
ai-proxy:
provider: gemini
auth:
header:
Authorization: Bearer ${GEMINI_API_KEY}
options:
model: gemini-3.5-flash
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Review the diff for unexpected changes or deletions before syncing these services:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-gemini
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-gemini
❶ Specify the provider to be gemini.
❷ Replace with your Gemini API key in the Authorization header.
❸ Specify the name of the Gemini model.
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-proxy-plugin-config
spec:
plugins:
- name: ai-proxy
config:
provider: gemini
auth:
header:
Authorization: "Bearer <GEMINI_API_KEY>"
options:
model: gemini-3.5-flash
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: gemini-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-proxy-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
Apply the configuration to your cluster:
kubectl apply -f gemini-ic.yaml
❶ Specify the provider to be gemini.
❷ Replace with your Gemini API key in the Authorization header.
❸ Specify the name of the Gemini model.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: gemini-route
spec:
ingressClassName: apisix
http:
- name: gemini-route
match:
paths:
- /anything
methods:
- POST
plugins:
- name: ai-proxy
enable: true
config:
provider: gemini
auth:
header:
Authorization: "Bearer <GEMINI_API_KEY>"
options:
model: gemini-3.5-flash
Apply the configuration to your cluster:
kubectl apply -f gemini-ic.yaml
❶ Specify the provider to be gemini.
❷ Replace with your Gemini API key in the Authorization header.
❸ Specify the name of the Gemini model.
The configuration above proxies requests to the chat completion endpoint at https://generativelanguage.googleapis.com/v1beta/openai/chat/completions. To proxy requests to an embeddings model, explicitly configure the embeddings model endpoint in the override field.
Send a POST request to the route with a system prompt and a sample user question in the request body:
curl "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "You are a helpful AI assistant" },
{ "role": "user", "content": "What is the capital of France?" }
]
}'
You should receive a response similar to the following:
{
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "The capital of France is **Paris**.",
"role": "assistant"
}
}
],
"model": "gemini-3.5-flash",
"object": "chat.completion",
"usage": {
"completion_tokens": 8,
"prompt_tokens": 15,
"total_tokens": 41
},
...
}
Proxy to Vertex AI Chat Completion
The following example sends chat requests to Vertex AI using a Google Cloud service account. Vertex AI support was introduced in API7 Enterprise 3.9.2 and APISIX 3.15.0.
Before proceeding:
- Follow the Vertex AI project setup instructions to enable billing and the Vertex AI API.
- Create a service account, assign it the "Vertex AI User" role, and create a service account key in JSON format.
Your credentials file should look similar to the following:
{
"type": "service_account",
"project_id": "<GCP_PROJECT_ID>",
"private_key_id": "...",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "<SERVICE_ACCOUNT_EMAIL>",
"client_id": "....",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/<URL_ENCODED_SERVICE_ACCOUNT_EMAIL>",
"universe_domain": "googleapis.com"
}
Save the raw JSON for the ADC example and a JSON-encoded string for the Admin API example:
export GCP_SA_JSON="$(cat credentials.json)"
export GCP_SA_JSON_STRING="$(jq -Rs . < credentials.json)"
- Admin API
- ADC
- Ingress Controller
Create a route with the ai-proxy plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d @- <<EOF
{
"id": "ai-proxy-vertex-ai-route",
"uri": "/anything",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "vertex-ai",
"auth": {
"gcp": {
"service_account_json": $GCP_SA_JSON_STRING
}
},
"provider_conf": {
"project_id": "<GCP_PROJECT_ID>",
"region": "northamerica-northeast1"
},
"options": {
"model": "google/gemini-3.5-flash"
}
}
}
}
EOF
❶ Specify the provider to be vertex-ai.
❷ Provide the service account credentials as a JSON string.
❸ Replace with your Vertex AI project ID and region.
❹ Specify the name of the Gemini model through Vertex AI in the <publisher>/<model> format.
Create a route with the ai-proxy plugin:
services:
- name: vertex-ai-service
labels:
docs-example: ai-proxy-vertex-chat
routes:
- name: vertex-ai-route
uris:
- /anything
methods:
- POST
plugins:
ai-proxy:
provider: vertex-ai
auth:
gcp:
service_account_json: ${GCP_SA_JSON}
provider_conf:
project_id: <GCP_PROJECT_ID>
region: northamerica-northeast1
options:
model: google/gemini-3.5-flash
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Review the diff for unexpected changes or deletions before syncing these services:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-vertex-chat
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-vertex-chat
❶ Specify the provider to be vertex-ai.
❷ Provide the service account credentials as a JSON string.
❸ Replace with your Vertex AI project ID and region.
❹ Specify the name of the Gemini model through Vertex AI in the <publisher>/<model> format.
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-proxy-plugin-config
spec:
plugins:
- name: ai-proxy
config:
provider: vertex-ai
auth:
gcp:
service_account_json: '{"type":"service_account","project_id":"<GCP_PROJECT_ID>","private_key_id":"...","private_key":"-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----","client_email":"<SERVICE_ACCOUNT_EMAIL>","client_id":"...","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/<URL_ENCODED_SERVICE_ACCOUNT_EMAIL>","universe_domain":"googleapis.com"}'
provider_conf:
project_id: <GCP_PROJECT_ID>
region: northamerica-northeast1
options:
model: google/gemini-3.5-flash
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: vertex-ai-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-proxy-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
Apply the configuration to your cluster:
kubectl apply -f vertex-ai-ic.yaml
❶ Specify the provider to be vertex-ai.
❷ Provide the service account credentials as a JSON string.
❸ Replace with your Vertex AI project ID and region.
❹ Specify the name of the Gemini model through Vertex AI in the <publisher>/<model> format.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: vertex-ai-route
spec:
ingressClassName: apisix
http:
- name: vertex-ai-route
match:
paths:
- /anything
methods:
- POST
plugins:
- name: ai-proxy
enable: true
config:
provider: vertex-ai
auth:
gcp:
service_account_json: '{"type":"service_account","project_id":"<GCP_PROJECT_ID>","private_key_id":"...","private_key":"-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----","client_email":"<SERVICE_ACCOUNT_EMAIL>","client_id":"...","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/<URL_ENCODED_SERVICE_ACCOUNT_EMAIL>","universe_domain":"googleapis.com"}'
provider_conf:
project_id: <GCP_PROJECT_ID>
region: northamerica-northeast1
options:
model: google/gemini-3.5-flash
Apply the configuration to your cluster:
kubectl apply -f vertex-ai-ic.yaml
❶ Specify the provider to be vertex-ai.
❷ Provide the service account credentials as a JSON string.
❸ Replace with your Vertex AI project ID and region.
❹ Specify the name of the Gemini model through Vertex AI in the <publisher>/<model> format.
Send a POST request to the route with a system prompt and a sample user question in the request body:
curl "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "You are a mathematician" },
{ "role": "user", "content": "What is 1+1?" }
]
}'
You should receive a response similar to the following:
{
"choices": [
{
"message": {
"role": "assistant",
"content": "1 + 1 = 2\n"
},
"index": 0,
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"completion_tokens": 8,
"extra_properties": {
"google": {
"traffic_type": "ON_DEMAND"
}
},
"total_tokens": 19,
"prompt_tokens": 11
},
"object": "chat.completion",
"model": "google/gemini-3.5-flash",
...
}
Proxy to Vertex AI Embedding Models
The following example sends embedding requests to Vertex AI using a Google Cloud service account. Vertex AI support was introduced in API7 Enterprise 3.9.2 and APISIX 3.15.0.
Before proceeding:
- Follow the Vertex AI project setup instructions to enable billing and the Vertex AI API.
- Create a service account, assign it the "Vertex AI User" role, and create a service account key in JSON format.
Your credentials file should look similar to the following:
{
"type": "service_account",
"project_id": "<GCP_PROJECT_ID>",
"private_key_id": "...",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "<SERVICE_ACCOUNT_EMAIL>",
"client_id": "....",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/<URL_ENCODED_SERVICE_ACCOUNT_EMAIL>",
"universe_domain": "googleapis.com"
}
Save the raw JSON for the ADC example and a JSON-encoded string for the Admin API example:
export GCP_SA_JSON="$(cat credentials.json)"
export GCP_SA_JSON_STRING="$(jq -Rs . < credentials.json)"
- Admin API
- ADC
- Ingress Controller
Create a route with the ai-proxy plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d @- <<EOF
{
"id": "ai-proxy-vertex-ai-embeddings-route",
"uri": "/embeddings",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "vertex-ai",
"auth": {
"gcp": {
"service_account_json": $GCP_SA_JSON_STRING
}
},
"provider_conf": {
"project_id": "<GCP_PROJECT_ID>",
"region": "us-central1"
},
"options": {
"model": "gemini-embedding-001"
}
}
}
}
EOF
❶ Specify the provider to be vertex-ai.
❷ Provide the service account credentials as a JSON string.
❸ Replace with your Vertex AI project ID and region.
❹ Specify the name of the Vertex AI Gemini embedding model.
Create a route with the ai-proxy plugin:
services:
- name: vertex-ai-embeddings-service
labels:
docs-example: ai-proxy-vertex-embeddings
routes:
- name: vertex-ai-embeddings-route
uris:
- /embeddings
methods:
- POST
plugins:
ai-proxy:
provider: vertex-ai
auth:
gcp:
service_account_json: ${GCP_SA_JSON}
provider_conf:
project_id: <GCP_PROJECT_ID>
region: us-central1
options:
model: gemini-embedding-001
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Review the diff for unexpected changes or deletions before syncing these services:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-vertex-embeddings
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-vertex-embeddings
❶ Specify the provider to be vertex-ai.
❷ Provide the service account credentials as a JSON string.
❸ Replace with your Vertex AI project ID and region.
❹ Specify the name of the Vertex AI Gemini embedding model.
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-proxy-plugin-config
spec:
plugins:
- name: ai-proxy
config:
provider: vertex-ai
auth:
gcp:
service_account_json: '{"type":"service_account","project_id":"<GCP_PROJECT_ID>","private_key_id":"...","private_key":"-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----","client_email":"<SERVICE_ACCOUNT_EMAIL>","client_id":"...","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/<URL_ENCODED_SERVICE_ACCOUNT_EMAIL>","universe_domain":"googleapis.com"}'
provider_conf:
project_id: <GCP_PROJECT_ID>
region: us-central1
options:
model: gemini-embedding-001
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: vertex-ai-embeddings-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /embeddings
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-proxy-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
Apply the configuration to your cluster:
kubectl apply -f vertex-ai-embeddings-ic.yaml
❶ Specify the provider to be vertex-ai.
❷ Provide the service account credentials as a JSON string.
❸ Replace with your Vertex AI project ID and region.
❹ Specify the name of the Vertex AI Gemini embedding model.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: vertex-ai-embeddings-route
spec:
ingressClassName: apisix
http:
- name: vertex-ai-embeddings-route
match:
paths:
- /embeddings
methods:
- POST
plugins:
- name: ai-proxy
enable: true
config:
provider: vertex-ai
auth:
gcp:
service_account_json: '{"type":"service_account","project_id":"<GCP_PROJECT_ID>","private_key_id":"...","private_key":"-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----","client_email":"<SERVICE_ACCOUNT_EMAIL>","client_id":"...","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/<URL_ENCODED_SERVICE_ACCOUNT_EMAIL>","universe_domain":"googleapis.com"}'
provider_conf:
project_id: <GCP_PROJECT_ID>
region: us-central1
options:
model: gemini-embedding-001
Apply the configuration to your cluster:
kubectl apply -f vertex-ai-embeddings-ic.yaml
❶ Specify the provider to be vertex-ai.
❷ Provide the service account credentials as a JSON string.
❸ Replace with your Vertex AI project ID and region.
❹ Specify the name of the Vertex AI Gemini embedding model.
Send a POST request to the route with an input string:
curl "http://127.0.0.1:9080/embeddings" -X POST \
-H "Content-Type: application/json" \
-d '{
"input": "hello world"
}'
You should receive a response similar to the following:
{
"model": "gemini-embedding-001",
"usage": {
"total_tokens": 2,
"prompt_tokens": 2
},
"object": "list",
"data": [
{
"index": 0,
"object": "embedding",
"embedding": [
-0.0241838414222,
0.0098769934847951,
0.0074856607243419,
-0.067302219569683,
...
]
}
]
}
Proxy to OpenAI Embedding Models
The following example configures ai-proxy to send embedding requests to OpenAI.
Obtain an OpenAI API key and optionally save it to an environment variable:
export OPENAI_API_KEY="<OPENAI_API_KEY>"
- Admin API
- ADC
- Ingress Controller
Create a route with the ai-proxy plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d @- <<EOF
{
"id": "ai-proxy-route",
"uri": "/embeddings",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer $OPENAI_API_KEY"
}
},
"options": {
"model": "text-embedding-3-small",
"encoding_format": "float"
}
}
}
}
EOF
❶ Select the openai provider. When the request body contains input, the plugin detects an Embeddings request and sends it to https://api.openai.com/v1/embeddings.
❷ Attach OpenAI API key in the Authorization header.
❸ Specify the name of the embedding model.
❹ Add an additional parameter encoding_format to configure returned embedding vector to be a list of floating point numbers.
Create a route with the ai-proxy plugin:
services:
- name: openai-embeddings-service
labels:
docs-example: ai-proxy-openai-embeddings
routes:
- name: openai-embeddings-route
uris:
- /embeddings
methods:
- POST
plugins:
ai-proxy:
provider: openai
auth:
header:
Authorization: Bearer ${OPENAI_API_KEY}
options:
model: text-embedding-3-small
encoding_format: float
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Review the diff for unexpected changes or deletions before syncing these services:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-openai-embeddings
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=ai-proxy-openai-embeddings
❶ Select the openai provider. When the request body contains input, the plugin detects an Embeddings request and sends it to https://api.openai.com/v1/embeddings.
❷ Attach OpenAI API key in the Authorization header.
❸ Specify the name of the embedding model.
❹ Add an additional parameter encoding_format to configure returned embedding vector to be a list of floating point numbers.
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-proxy-plugin-config
spec:
plugins:
- name: ai-proxy
config:
provider: openai
auth:
header:
Authorization: "Bearer <OPENAI_API_KEY>"
options:
model: text-embedding-3-small
encoding_format: float
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: openai-embeddings-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /embeddings
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-proxy-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
Apply the configuration to your cluster:
kubectl apply -f openai-embeddings-ic.yaml
❶ Select the openai provider. When the request body contains input, the plugin detects an Embeddings request and sends it to https://api.openai.com/v1/embeddings.