Skip to main content

OpenAI Compatible AIProxy Agents

AIProxy agents can be invoked through OpenAI-compatible endpoints, so you can talk to them with the same request/response shapes and the same official OpenAI SDKs you already use.

Two OpenAI APIs are supported:

APIEndpoint
Chat CompletionsPOST /api/v2/aiproxy/chat/completions
ResponsesPOST /api/v2/aiproxy/responses

Both endpoints support:

  • Streaming and non-streaming responses ("stream": true / false). See Streaming for the event formats.
  • Server tools — web search, image generation, speech generation and workbench (code execution), which run entirely on the server.
  • Client tools — standard OpenAI function calling, with the tool executed on your side.
  • Input files — images and documents sent inline (base64 data URI), by URL, or by Volatile Knowledge file_id. See Input files.
Base URL and authentication

All examples use https://api.serenitystar.ai as the base URL and a placeholder YOUR_API_KEY.

Authenticate with your API key using either:

  • the dedicated header — X-API-KEY: YOUR_API_KEY, or
  • a bearer token — Authorization: Bearer YOUR_API_KEY.

Because the bearer form is accepted, the official OpenAI SDKs work out of the box — just set the SDK's api_key and point base_url at the AIProxy endpoint.

The model identifier

Unlike a plain OpenAI request, the model field selects which AIProxy agent to run and which underlying model to route to. It is a colon-separated identifier:

{agentCode}:{vendor}:{model}
PartRequiredDescription
agentCodeYesThe code of your AIProxy agent.
vendorYesThe AI vendor to route to (e.g. OpenAI, Anthropic, GoogleVertex).
modelYesThe model identifier at that vendor (e.g. gpt-5.6-luna).

Examples:

  • my-aiproxy-agent:OpenAI:gpt-5.6-luna
  • my-aiproxy-agent:Anthropic:claude-fable-5
  • my-aiproxy-agent:GoogleVertex:gemini-3.5-flash
note

Only the first two colons are used as separators, so model identifiers that themselves contain colons (for example an AWS Bedrock ARN) are preserved.

Serenity* Star custom fields

Serenity* Star custom execution metadata is sent as top-level fields of the request body. All fields are optional:

FieldDescription
channelThe channel the execution is attributed to.
user_identifierIdentifier of the end user.
group_identifierIdentifier of the user's group.
{
"model": "my-aiproxy-agent:OpenAI:gpt-5.6-luna",
// ...
"channel": "my-channel",
"user_identifier": "user-123",
"group_identifier": "group-abc"
}

These fields aren't part of the standard OpenAI schema, so when using an OpenAI SDK you pass them via the SDK's extra_body parameter, and the SDK merges them into the top level of the request body for you.


Input files

Both APIs let you attach images and documents to a user message as structured content parts. Each part points at a file in one of three ways:

SourceHow you supply itWhat happens
Base64 data URIEmbed the file inline as data:<mime>;base64,....Uploaded as Volatile Knowledge on your behalf.
Remote URLA reachable URL to the file.Downloaded, then stored as Volatile Knowledge.
file_idThe ID of a file already uploaded as Volatile Knowledge.Reused as-is — nothing is uploaded again.

Documents attached to an AIProxy agent become Volatile Knowledge so the agent can reason over them. Files are validated against your instance's accepted MIME types (PDF, common image formats, plain text, CSV, and Office documents) and maximum file size. When a filename is omitted, one is synthesized from the MIME type.

The three sources above are available in both APIs; only the content-part shape differs. See the per-API examples under Chat Completions and Responses.


Chat Completions

POST /api/v2/aiproxy/chat/completions

Uses the OpenAI Chat Completions shape: a messages array, max_completion_tokens, stream, and an optional tools array.

Simple request

cURL
curl https://api.serenitystar.ai/api/v2/aiproxy/chat/completions \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:OpenAI:gpt-5.6-luna",
"stream": false,
"max_completion_tokens": 5000,
"messages": [
{ "role": "user", "content": "Hello! Tell me a fun fact about Valencia." }
],
"channel": "my-channel",
"user_identifier": "user-123",
"group_identifier": "group-abc"
}'

Set "stream": true to receive chat.completion.chunk events over SSE instead of a single response.

Tools

Two kinds of tools can be declared in the tools array. They can be combined in a single request.

Server tools

Server tools run entirely on the server — there is no round-trip. Send one request and the agent invokes the tool internally and returns the final answer. The response choices still expose the trace: an assistant message with tool_calls, followed by the final assistant content.

ToolDescriptionDeclarationOptional fields
Web searchSearches the web and grounds the answer in what it finds.{ "type": "web_search" }model, vendor
Image generationGenerates images from the prompt.{ "type": "image_generation" }model, vendor
Speech generationSynthesizes speech audio from text.{ "type": "speech_generation" }model, vendor, voice, speed
WorkbenchRuns code in an ephemeral micro-VM — a dedicated, isolated environment spun up per agent session so code executes safely.{ "type": "workbench" }

When model/vendor (and the speech voice/speed) are omitted, the agent falls back to its configured defaults.

cURL — web search
curl https://api.serenitystar.ai/api/v2/aiproxy/chat/completions \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:OpenAI:gpt-5.6-luna",
"stream": false,
"max_completion_tokens": 5000,
"messages": [
{ "role": "user", "content": "Search the Web for Serenity Star AI and tell me what you find." }
],
"tools": [
{ "type": "web_search", "model": "gpt-5.4-mini", "vendor": "OpenAI" }
],
"channel": "my-channel"
}'

You can declare several server tools at once and let the agent pick the right one for the prompt:

"tools": [
{ "type": "web_search", "model": "gpt-5.4-mini", "vendor": "OpenAI" },
{ "type": "image_generation", "model": "gpt-image-1", "vendor": "OpenAI" },
{ "type": "speech_generation", "model": "tts-1", "vendor": "OpenAI", "voice": "echo", "speed": 2.0 },
{ "type": "workbench" }
]

Client tools

Client tools are standard OpenAI function calling: the model decides to call the function, you execute it on your side, and you send the result back for the model to complete its answer. In Chat Completions, tools use the nested function shape.

Step 1 — request that triggers the tool call.

cURL
curl https://api.serenitystar.ai/api/v2/aiproxy/chat/completions \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:Anthropic:claude-fable-5",
"stream": false,
"max_completion_tokens": 512,
"messages": [
{ "role": "user", "content": "What is the weather like in Paris right now? Use the tool." }
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "The city name" }
},
"required": ["city"]
}
}
}
],
"channel": "my-channel"
}'

The response comes back with finish_reason: "tool_calls" and a tool_call carrying an id and the arguments:

{
"choices": [
{
"finish_reason": "tool_calls",
"message": {
"role": "assistant",
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": { "name": "get_weather", "arguments": "{\"city\":\"Paris\"}" }
}
]
}
}
]
}

Step 2 — run the function and send the result back. Append the assistant message (with the tool_calls) and a role: "tool" message whose tool_call_id matches the id from step 1.

cURL
curl https://api.serenitystar.ai/api/v2/aiproxy/chat/completions \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:Anthropic:claude-fable-5",
"stream": false,
"max_completion_tokens": 512,
"messages": [
{ "role": "user", "content": "What is the weather like in Paris right now? Use the tool." },
{
"role": "assistant",
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": { "name": "get_weather", "arguments": "{\"city\":\"Paris\"}" }
}
]
},
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "{\"city\":\"Paris\",\"temperature_c\":18,\"condition\":\"light rain\",\"humidity\":72}"
}
],
"channel": "my-channel"
}'

The final response contains the assistant answer that reflects the tool result.

Input files

Add attachments as content parts inside a user message's content array. See Input files for how each source maps to Volatile Knowledge.

  • Images use an image_url part with a nested url (remote URL or base64 data URI).
  • Documents use a file part with either a file_id or an inline file_data, plus an optional filename.
cURL — remote image, base64 image, Volatile Knowledge file, and base64 document
curl https://api.serenitystar.ai/api/v2/aiproxy/chat/completions \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:GoogleVertex:gemini-3.5-flash",
"stream": false,
"max_completion_tokens": 5000,
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "Analyse all attached files." },
{
"type": "image_url",
"image_url": { "url": "https://example.com/image.png" }
},
{
"type": "image_url",
"image_url": { "url": "data:image/png;base64,iVBORw0KGgo..." }
},
{
"type": "file",
"file": { "file_id": "3eb85cee-cfdb-bfd9-3291-3a22798665a2" }
},
{
"type": "file",
"file": {
"filename": "report.pdf",
"file_data": "data:application/pdf;base64,JVBERi0xLjcK..."
}
}
]
}
],
"channel": "my-channel"
}'

The four parts show, in order: an image by remote URL, an image as an inline base64 data URI, a document by file_id, and a document as an inline base64 data URI. Point file_data at a URL to attach a remote document.


Responses

POST /api/v2/aiproxy/responses

Uses the OpenAI Responses shape: an input array, max_output_tokens, stream, and an optional tools array. Note that in the Responses API tools are a flat array ({ "type": "function", "name", ... }) and the model returns a function_call output item.

Simple request

cURL
curl https://api.serenitystar.ai/api/v2/aiproxy/responses \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:OpenAI:gpt-5.6-luna",
"stream": false,
"max_output_tokens": 5000,
"input": [
{ "role": "user", "content": "Hello! Tell me a fun fact about Valencia." }
],
"channel": "my-channel",
"user_identifier": "user-123",
"group_identifier": "group-abc"
}'

Tools

As with Chat Completions, both server tools and client tools are declared in the tools array and can be combined.

Server tools

The available server tools and their optional fields are identical to Chat Completions:

"tools": [
{ "type": "web_search", "model": "gpt-5.4-mini", "vendor": "OpenAI" },
{ "type": "image_generation", "model": "gpt-image-1", "vendor": "OpenAI" },
{ "type": "speech_generation", "model": "tts-1", "vendor": "OpenAI", "voice": "echo", "speed": 2.0 },
{ "type": "workbench" }
]
cURL — web search
curl https://api.serenitystar.ai/api/v2/aiproxy/responses \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:OpenAI:gpt-5.6-luna",
"stream": false,
"max_output_tokens": 5000,
"input": [
{ "role": "user", "content": "Search the Web for Serenity Star AI and tell me what you find." }
],
"tools": [
{ "type": "web_search", "model": "gpt-5.4-mini", "vendor": "OpenAI" }
],
"channel": "my-channel"
}'

The server runs the tool internally and returns the final answer. The output array still shows the trace: a function_call, a function_call_output, and the final assistant message.

Client tools

Client tools follow OpenAI function calling for the Responses API. Tools are declared flat, and the model returns a function_call output item (with a call_id, name, and arguments).

Step 1 — request that triggers the function call.

cURL
curl https://api.serenitystar.ai/api/v2/aiproxy/responses \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:Anthropic:claude-fable-5",
"stream": false,
"max_output_tokens": 5000,
"input": [
{ "role": "user", "content": "What is the weather like in Berlin right now? Use the tool." }
],
"tools": [
{
"type": "function",
"name": "get_weather",
"description": "Get the current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "The city name" }
},
"required": ["city"]
}
}
],
"channel": "my-channel"
}'

The response output contains a function_call item:

{
"output": [
{
"type": "function_call",
"call_id": "call_abc123",
"name": "get_weather",
"arguments": "{\"city\":\"Berlin\"}"
}
]
}

Step 2 — run the function and send the result back. Replay the function_call in input, then append a function_call_output item with the same call_id.

cURL
curl https://api.serenitystar.ai/api/v2/aiproxy/responses \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:Anthropic:claude-fable-5",
"stream": false,
"max_output_tokens": 5000,
"input": [
{ "role": "user", "content": "What is the weather like in Berlin right now? Use the tool." },
{
"type": "function_call",
"call_id": "call_abc123",
"name": "get_weather",
"arguments": "{\"city\":\"Berlin\"}"
},
{
"type": "function_call_output",
"call_id": "call_abc123",
"output": "{\"city\":\"Berlin\",\"temperature_c\":12,\"condition\":\"overcast\",\"humidity\":80}"
}
],
"tools": [
{
"type": "function",
"name": "get_weather",
"description": "Get the current weather for a given city",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
],
"channel": "my-channel"
}'

The final response contains the assistant message that reflects the tool result.

Input files

Add attachments as content parts inside an input message's content array. See Input files for how each source maps to Volatile Knowledge.

  • Images use an input_image part with an image_url string (remote URL or base64 data URI).
  • Documents use an input_file part with either a file_id or a file_data string, plus an optional filename.
cURL — remote image, base64 image, Volatile Knowledge file, and base64 document
curl https://api.serenitystar.ai/api/v2/aiproxy/responses \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"model": "my-aiproxy-agent:GoogleVertex:gemini-3.5-flash",
"stream": false,
"max_output_tokens": 5000,
"input": [
{
"role": "user",
"content": [
{ "type": "input_text", "text": "Analyse all attached files." },
{
"type": "input_image",
"image_url": "https://example.com/image.png"
},
{
"type": "input_image",
"image_url": "data:image/png;base64,iVBORw0KGgo..."
},
{
"type": "input_file",
"file_id": "3eb85cee-cfdb-bfd9-3291-3a22798665a2"
},
{
"type": "input_file",
"filename": "report.pdf",
"file_data": "data:application/pdf;base64,JVBERi0xLjcK..."
}
]
}
],
"channel": "my-channel"
}'

The parts map the same way as in Chat Completions: an image by remote URL, an image as an inline base64 data URI, a document by file_id, and a document as an inline base64 data URI. Point file_data at a URL to attach a remote document.