Responses API
The OpenAI Responses API (POST /v1/responses) for Codex and newer OpenAI clients, with streaming events, tools and reasoning.
Newer OpenAI clients, including Codex, use the OpenAI Responses API instead of chat completions. The gateway accepts it at https://ai.helipod.io/v1/responses for every model, with the same key, prices, limits and errors as the other endpoints.
/v1/responsesResponses are stateless: every request carries the whole conversation in input. Nothing is stored, so previous_response_id, GET /v1/responses/{id} and background responses are not available. Codex already works this way (store: false).
Request
Prop
Type
store, include, prompt_cache_key, metadata and client_metadata are accepted and have no effect. Prompt caching happens automatically where the model supports it.
Input items
| Item | Meaning |
|---|---|
{ "type": "message", "role": "user", "content": … } | A user turn. content is a string or input_text and input_image parts. |
role: "system" or "developer" | Instructions. Before the first turn they join instructions. |
role: "assistant" with output_text parts | An earlier answer. |
function_call / function_call_output | A tool call the model made and its result, matched by call_id. |
custom_tool_call / custom_tool_call_output | The same for a custom (freeform) tool. |
reasoning | Earlier reasoning. Its summary text is passed back to models that want it. |
Examples
curl https://ai.helipod.io/v1/responses \
-H "Authorization: Bearer hel_ai_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3",
"instructions": "You are a concise assistant.",
"input": "Explain what a VPS is in two sentences.",
"max_output_tokens": 2000
}'Response
{
"id": "resp_9f2c…",
"object": "response",
"status": "completed",
"model": "glm-5.3",
"output": [
{ "type": "reasoning", "id": "rs_…", "summary": [{ "type": "summary_text", "text": "The user wants…" }] },
{
"type": "message", "id": "msg_…", "role": "assistant", "status": "completed",
"content": [{ "type": "output_text", "text": "A VPS is…", "annotations": [] }]
}
],
"usage": {
"input_tokens": 31, "input_tokens_details": { "cached_tokens": 0 },
"output_tokens": 96, "output_tokens_details": { "reasoning_tokens": 40 },
"total_tokens": 127
}
}statusiscompleted, orincompletewhen the output cap was reached (incomplete_details.reason: "max_output_tokens").- A model's thinking comes back as a
reasoningitem with the text insummary. - Tool calls come back as
function_callitems (call_id,name,arguments) orcustom_tool_callitems (input). usageis what you are billed for. The response headers (x-request-id,x-helipod-model) are the same as on chat completions.
Streaming
With "stream": true the answer arrives as server-sent events, each with a type and a sequence_number:
| Event | When |
|---|---|
response.created, response.in_progress | First, with the response object. |
response.output_item.added / .done | Each output item starts and ends (reasoning, message, tool call). |
response.reasoning_summary_text.delta | Reasoning text. |
response.output_text.delta / .done | Answer text. |
response.content_part.added / .done | The text part of a message. |
response.function_call_arguments.delta / .done | Arguments of a function call. |
response.custom_tool_call_input.done | The input of a custom tool call. |
response.completed | Last, with the full response and usage. response.incomplete when the cap was reached. |
response.failed | The request failed after streaming started; response.error says why. |
Keep-alive comment lines (: keep-alive) can arrive while a model starts, as on the other endpoints; SSE clients ignore them. Errors before the stream starts are normal JSON errors with the real status, see Limits and errors.
Tools
{
"tools": [
{ "type": "function", "name": "get_weather", "description": "Weather for a city",
"parameters": { "type": "object", "properties": { "city": { "type": "string" } }, "required": ["city"] } },
{ "type": "custom", "name": "apply_patch", "description": "Apply a patch in the given format" },
{ "type": "namespace", "name": "mcp__helipod", "description": "Helipod cloud tools",
"tools": [{ "type": "function", "name": "list_projects", "parameters": { "type": "object", "properties": {} } }] }
]
}- function tools work as in chat completions.
- custom (freeform) tools take raw text. The call comes back as a
custom_tool_callwith the text ininput. - namespace groups tools, as Codex does for each MCP server. A call to a tool in a namespace comes back with both
nameandnamespace.
Send the result back as a function_call_output (or custom_tool_call_output) item with the same call_id, after the call itself.
Differences from OpenAI
- Stateless only: no stored responses,
previous_response_id, conversations or background mode. - Built-in tools (web search, file search, computer use, code interpreter, image generation) are not available and are ignored.
- File inputs (
input_file) and audio are not supported; images are. - Encrypted reasoning is not returned; reasoning comes back as readable summary text.