Why Responses? The Responses API is the recommended way to build on Gloo AI. It uses the OpenAI-compatible Responses request shape and is guarded by default — every request runs the same guardrails, values-aligned
tradition responses, and output moderation that power Completions V2, with no extra configuration.Prerequisites
Before starting, ensure you have:- A Gloo AI Studio account
- Your API key from the API Credentials page
- Authentication setup - Complete the Authentication Tutorial first
Understanding the Responses API
All requests go to a single guarded endpoint: POST/ai/v2/guarded/responses
Key Request Fields
| Parameter | Description |
|---|---|
model | The exact model ID. The Responses API is pinned-model only — no auto-routing or model_family. |
input | A plain string, or an array of {role, content} items for multi-turn conversations. |
instructions | Optional system-level guidance. Replaces the Completions system role message. |
tradition | Optional theological tradition for values-aligned answers (e.g. "evangelical"). |
stream | Set true to receive the response as Server-Sent Events. |
max_output_tokens | Optional cap on response length. |
output[] array. See Example 1’s “Understanding the Response” for the full shape and how to extract the text.
Guardrail Behavior
Values-aligned static answers arrive as normal messages. When guardrails intervene with a curated, tradition-appropriate answer, it comes back as a regularmessage item in output[] — identical shape to a model answer. Your client needs no special handling; just extract the text as usual.
Hard blocks return 403. Requests that guardrails reject outright return an HTTP 403:
{
"detail": {
"message": "Your request was rejected as it violates content policies.",
"type": "content_policy_violation",
"code": "content_policy_violation",
"retryable": false
}
}
Moving from Completions
If you already use Completions V2, the migration is mostly a rename:| Completions V2 | Responses API |
|---|---|
POST /ai/v2/guarded/chat/completions | POST /ai/v2/guarded/responses |
messages | input |
system role message | instructions |
max_tokens | max_output_tokens |
choices[].message.content (string) | output[] (typed items) |
tradition | tradition (unchanged) |
Auto-routing and
model_family selection remain Completions V2 features. The Responses API is pinned-model only — you specify an exact model on every request.Example 1: Basic Guarded Response with Tradition
Send a plain-stringinput and a tradition to get a values-aligned answer:
import os
import requests
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("GLOO_API_KEY", "YOUR_API_KEY")
API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses"
def make_basic_response(message, tradition="evangelical"):
"""Example 1: Basic guarded response with a theological tradition."""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
payload = {
"model": "gloo-anthropic-claude-sonnet-4.6",
"input": message,
"tradition": tradition,
"max_output_tokens": 256,
}
response = requests.post(API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
result = make_basic_response("How can our small group support a grieving member?")
print(result)
require("dotenv").config();
const API_KEY = process.env.GLOO_API_KEY || "YOUR_API_KEY";
const API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
async function makeBasicResponse(message, tradition = "evangelical") {
const payload = {
model: "gloo-anthropic-claude-sonnet-4.6",
input: message,
tradition: tradition,
max_output_tokens: 256,
};
const response = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}: ${await response.text()}`);
}
return response.json();
}
makeBasicResponse("How can our small group support a grieving member?").then(console.log);
import { config } from "dotenv";
config();
const API_KEY = process.env.GLOO_API_KEY || "YOUR_API_KEY";
const API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
async function makeBasicResponse(message: string, tradition: string = "evangelical"): Promise<any> {
const payload = {
model: "gloo-anthropic-claude-sonnet-4.6",
input: message,
tradition: tradition,
max_output_tokens: 256,
};
const response = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}: ${await response.text()}`);
}
return response.json();
}
makeBasicResponse("How can our small group support a grieving member?").then(console.log);
<?php
require_once 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad();
$apiKey = $_ENV['GLOO_API_KEY'] ?? getenv('GLOO_API_KEY') ?: 'YOUR_API_KEY';
$apiUrl = 'https://platform.ai.gloo.com/ai/v2/guarded/responses';
function makeBasicResponse(string $message, string $tradition = 'evangelical'): array {
global $apiKey, $apiUrl;
$payload = json_encode([
'model' => 'gloo-anthropic-claude-sonnet-4.6',
'input' => $message,
'tradition' => $tradition,
'max_output_tokens' => 256,
]);
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
throw new RuntimeException('API request failed: ' . $error);
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException('API request failed with status ' . $status . ': ' . $body);
}
return json_decode($body, true);
}
print_r(makeBasicResponse('How can our small group support a grieving member?'));
?>
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
const apiURL = "https://platform.ai.gloo.com/ai/v2/guarded/responses"
func makeBasicResponse(message, tradition string) (map[string]interface{}, error) {
payload := map[string]interface{}{
"model": "gloo-anthropic-claude-sonnet-4.6",
"input": message,
"tradition": tradition,
"max_output_tokens": 256,
}
body, _ := json.Marshal(payload)
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(body))
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+os.Getenv("GLOO_API_KEY"))
req.Header.Add("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(respBody))
}
var result map[string]interface{}
json.Unmarshal(respBody, &result)
return result, nil
}
func main() {
result, err := makeBasicResponse("How can our small group support a grieving member?", "evangelical")
if err != nil {
fmt.Println("Error:", err)
return
}
out, _ := json.MarshalIndent(result, "", " ")
fmt.Println(string(out))
}
import com.google.gson.Gson;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;
public class BasicResponse {
private static final String API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
private static final String API_KEY = System.getenv().getOrDefault("GLOO_API_KEY", "YOUR_API_KEY");
private static final Gson gson = new Gson();
public static Map<String, Object> makeBasicResponse(String message, String tradition) throws Exception {
Map<String, Object> payload = new HashMap<>();
payload.put("model", "gloo-anthropic-claude-sonnet-4.6");
payload.put("input", message);
payload.put("tradition", tradition);
payload.put("max_output_tokens", 256);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + API_KEY)
.POST(HttpRequest.BodyPublishers.ofString(gson.toJson(payload)))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("API request failed with status " + response.statusCode() + ": " + response.body());
}
return gson.fromJson(response.body(), Map.class);
}
public static void main(String[] args) throws Exception {
Map<String, Object> result = makeBasicResponse(
"How can our small group support a grieving member?", "evangelical");
System.out.println(gson.toJson(result));
}
}
Understanding the Response
The answer comes back as a typedoutput[] array — a message item whose content[] holds output_text parts:
{
"id": "resp_...",
"object": "response",
"model": "gloo-anthropic-claude-sonnet-4.6",
"output": [
{
"type": "message",
"role": "assistant",
"content": [
{ "type": "output_text", "text": "Grief support starts with presence..." }
]
}
],
"usage": { "input_tokens": 24, "output_tokens": 38, "total_tokens": 62 }
}
output[] for message items and join their output_text parts — the cookbook samples do exactly this in an extractText helper.
What You’ll See
Running the full sample prints one block per example, then the final banner:=== Gloo AI Guarded Responses API Test ===
Example 1: Basic Guarded Response (tradition=evangelical)
Testing: How can our small group support a grieving member?
Model used: gloo-anthropic-claude-sonnet-4.6
Response: I'm so sorry your group is walking through this loss. A few ways to sup...
Usage: {"input_tokens": 24, "output_tokens": 38, "total_tokens": 62}
✓ Example 1 passed
Example 2: Instructions + Multi-Turn Input
Useinstructions for system-level guidance and pass the conversation as an input array. The history alternates user → assistant → user (three turns), so the model continues the conversation with full context:
import os
import requests
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("GLOO_API_KEY", "YOUR_API_KEY")
API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses"
def make_instructions_response(instructions, input_items):
"""Example 2: Instructions plus multi-turn input array (alternating user/assistant roles)."""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
payload = {
"model": "gloo-anthropic-claude-sonnet-4.6",
"instructions": instructions,
"input": input_items,
"max_output_tokens": 256,
}
response = requests.post(API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
result = make_instructions_response(
"You are a compassionate pastoral assistant. Keep answers brief and warm.",
[
{
"role": "user",
"content": "I've been asked to lead a grief support group at church. Where do I start?",
},
{
"role": "assistant",
"content": "That's a meaningful calling. Start with prayerful preparation — ask God to prepare your own heart before you prepare the room.",
},
{
"role": "user",
"content": "What should I do in the very first meeting?",
},
],
)
print(result)
require("dotenv").config();
const API_KEY = process.env.GLOO_API_KEY || "YOUR_API_KEY";
const API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
async function makeInstructionsResponse(instructions, inputItems) {
const payload = {
model: "gloo-anthropic-claude-sonnet-4.6",
instructions: instructions,
input: inputItems,
max_output_tokens: 256,
};
const response = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}: ${await response.text()}`);
}
return response.json();
}
makeInstructionsResponse(
"You are a compassionate pastoral assistant. Keep answers brief and warm.",
[
{
role: "user",
content: "I've been asked to lead a grief support group at church. Where do I start?",
},
{
role: "assistant",
content: "That's a meaningful calling. Start with prayerful preparation — ask God to prepare your own heart before you prepare the room.",
},
{
role: "user",
content: "What should I do in the very first meeting?",
},
]
).then(console.log);
import { config } from "dotenv";
config();
const API_KEY = process.env.GLOO_API_KEY || "YOUR_API_KEY";
const API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
async function makeInstructionsResponse(instructions: string, inputItems: any[]): Promise<any> {
const payload = {
model: "gloo-anthropic-claude-sonnet-4.6",
instructions: instructions,
input: inputItems,
max_output_tokens: 256,
};
const response = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}: ${await response.text()}`);
}
return response.json();
}
makeInstructionsResponse(
"You are a compassionate pastoral assistant. Keep answers brief and warm.",
[
{
role: "user",
content: "I've been asked to lead a grief support group at church. Where do I start?",
},
{
role: "assistant",
content: "That's a meaningful calling. Start with prayerful preparation — ask God to prepare your own heart before you prepare the room.",
},
{
role: "user",
content: "What should I do in the very first meeting?",
},
]
).then(console.log);
<?php
require_once 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad();
$apiKey = $_ENV['GLOO_API_KEY'] ?? getenv('GLOO_API_KEY') ?: 'YOUR_API_KEY';
$apiUrl = 'https://platform.ai.gloo.com/ai/v2/guarded/responses';
function makeInstructionsResponse(string $instructions, array $inputItems): array {
global $apiKey, $apiUrl;
$payload = json_encode([
'model' => 'gloo-anthropic-claude-sonnet-4.6',
'instructions' => $instructions,
'input' => $inputItems,
'max_output_tokens' => 256,
]);
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
throw new RuntimeException('API request failed: ' . $error);
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException('API request failed with status ' . $status . ': ' . $body);
}
return json_decode($body, true);
}
print_r(makeInstructionsResponse(
'You are a compassionate pastoral assistant. Keep answers brief and warm.',
[
['role' => 'user', 'content' => "I've been asked to lead a grief support group at church. Where do I start?"],
['role' => 'assistant', 'content' => "That's a meaningful calling. Start with prayerful preparation — ask God to prepare your own heart before you prepare the room."],
['role' => 'user', 'content' => 'What should I do in the very first meeting?'],
]
));
?>
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
const apiURL = "https://platform.ai.gloo.com/ai/v2/guarded/responses"
func makeInstructionsResponse(instructions string, inputItems []map[string]interface{}) (map[string]interface{}, error) {
payload := map[string]interface{}{
"model": "gloo-anthropic-claude-sonnet-4.6",
"instructions": instructions,
"input": inputItems,
"max_output_tokens": 256,
}
body, _ := json.Marshal(payload)
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(body))
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+os.Getenv("GLOO_API_KEY"))
req.Header.Add("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(respBody))
}
var result map[string]interface{}
json.Unmarshal(respBody, &result)
return result, nil
}
func main() {
result, err := makeInstructionsResponse(
"You are a compassionate pastoral assistant. Keep answers brief and warm.",
[]map[string]interface{}{
{"role": "user", "content": "I've been asked to lead a grief support group at church. Where do I start?"},
{"role": "assistant", "content": "That's a meaningful calling. Start with prayerful preparation — ask God to prepare your own heart before you prepare the room."},
{"role": "user", "content": "What should I do in the very first meeting?"},
},
)
if err != nil {
fmt.Println("Error:", err)
return
}
out, _ := json.MarshalIndent(result, "", " ")
fmt.Println(string(out))
}
import com.google.gson.Gson;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class InstructionsResponse {
private static final String API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
private static final String API_KEY = System.getenv().getOrDefault("GLOO_API_KEY", "YOUR_API_KEY");
private static final Gson gson = new Gson();
public static Map<String, Object> makeInstructionsResponse(String instructions, List<Map<String, Object>> inputItems) throws Exception {
Map<String, Object> payload = new HashMap<>();
payload.put("model", "gloo-anthropic-claude-sonnet-4.6");
payload.put("instructions", instructions);
payload.put("input", inputItems);
payload.put("max_output_tokens", 256);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + API_KEY)
.POST(HttpRequest.BodyPublishers.ofString(gson.toJson(payload)))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("API request failed with status " + response.statusCode() + ": " + response.body());
}
return gson.fromJson(response.body(), Map.class);
}
public static void main(String[] args) throws Exception {
Map<String, Object> result = makeInstructionsResponse(
"You are a compassionate pastoral assistant. Keep answers brief and warm.",
List.of(
Map.of("role", "user", "content", "I've been asked to lead a grief support group at church. Where do I start?"),
Map.of("role", "assistant", "content", "That's a meaningful calling. Start with prayerful preparation — ask God to prepare your own heart before you prepare the room."),
Map.of("role", "user", "content", "What should I do in the very first meeting?")
));
System.out.println(gson.toJson(result));
}
}
What You’ll See
The reply arrives as the samemessage item in output[] shown in Example 1, continuing the conversation.
Running the full sample prints the second block:
Example 2: Instructions + Multi-turn Input
Testing: three-turn conversation (user → assistant → user) with pastoral-care instructions
Model used: gloo-anthropic-claude-sonnet-4.6
Response: Start with introductions and a simple opening question. Invite each member to share...
Usage: {"input_tokens": 87, "output_tokens": 41, "total_tokens": 128}
✓ Example 2 passed
Example 3: Streaming (SSE)
Set"stream": true to receive the response as Server-Sent Events.
import json
import os
import requests
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("GLOO_API_KEY", "YOUR_API_KEY")
API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses"
def stream_response(message):
"""Example 3: Streaming via SSE; returns (accumulated_text, usage)."""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
payload = {
"model": "gloo-anthropic-claude-sonnet-4.6",
"input": message,
"stream": True,
"max_output_tokens": 256,
}
response = requests.post(API_URL, headers=headers, json=payload, stream=True)
response.raise_for_status()
text_parts = []
done_parts = []
usage = None
event = None
# Each data: payload is the flattened event object itself; lifecycle
# events are ignored, and response.completed carries usage but no output[].
for line in response.iter_lines(decode_unicode=True):
if line is None:
continue
if line.startswith("event:"):
event = line[len("event:"):].strip()
continue
if not line.startswith("data:"):
continue
data = json.loads(line[len("data:"):].strip())
if event == "response.output_text.delta":
delta = data.get("delta", "")
print(delta, end="", flush=True)
text_parts.append(delta)
elif event == "response.output_text.done":
done_parts.append(data.get("text", ""))
elif event == "response.completed":
final = data.get("response") or data
usage = final.get("usage")
elif event is not None and event.startswith("response."):
pass # lifecycle events — ignore
else:
raise RuntimeError(f"Stream terminated by event '{event}': {data}")
event = None
print()
text = "".join(text_parts) or "".join(done_parts)
return text, usage
text, usage = stream_response("Write a one-paragraph prayer for a new season of ministry.")
print(f"Streamed text ({len(text)} chars), usage: {usage}")
require("dotenv").config();
const API_KEY = process.env.GLOO_API_KEY || "YOUR_API_KEY";
const API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
async function streamResponse(message) {
const payload = {
model: "gloo-anthropic-claude-sonnet-4.6",
input: message,
stream: true,
max_output_tokens: 256,
};
const response = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}: ${await response.text()}`);
}
const textParts = [];
const doneParts = [];
let usage = null;
// Each data: payload is the flattened event object itself; lifecycle
// events are ignored, and response.completed carries usage but no output[].
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
let event = null;
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() ?? ""; // keep the incomplete last line
for (const rawLine of lines) {
const line = rawLine.replace(/\r$/, "");
if (line.startsWith("event:")) {
event = line.slice("event:".length).trim();
continue;
}
if (!line.startsWith("data:")) continue;
const data = JSON.parse(line.slice("data:".length).trim());
if (event === "response.output_text.delta") {
const delta = data.delta || "";
process.stdout.write(delta);
textParts.push(delta);
} else if (event === "response.output_text.done") {
doneParts.push(data.text || "");
} else if (event === "response.completed") {
const final = data.response || data;
usage = final.usage || null;
} else if (event !== null && event.startsWith("response.")) {
// lifecycle events — ignore
} else {
throw new Error(`Stream terminated by event '${event}': ${JSON.stringify(data)}`);
}
event = null;
}
}
process.stdout.write("\n");
return { text: textParts.join("") || doneParts.join(""), usage };
}
streamResponse("Write a one-paragraph prayer for a new season of ministry.").then(
({ text, usage }) => console.log(`Streamed text (${text.length} chars), usage: ${JSON.stringify(usage)}`)
);
import { config } from "dotenv";
config();
const API_KEY = process.env.GLOO_API_KEY || "YOUR_API_KEY";
const API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
async function streamResponse(message: string): Promise<{ text: string; usage: any }> {
const payload = {
model: "gloo-anthropic-claude-sonnet-4.6",
input: message,
stream: true,
max_output_tokens: 256,
};
const response = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}: ${await response.text()}`);
}
const textParts: string[] = [];
const doneParts: string[] = [];
let usage: any = null;
// Each data: payload is the flattened event object itself; lifecycle
// events are ignored, and response.completed carries usage but no output[].
const reader = response.body!.getReader();
const decoder = new TextDecoder();
let buffer = "";
let event: string | null = null;
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() ?? ""; // keep the incomplete last line
for (const rawLine of lines) {
const line = rawLine.replace(/\r$/, "");
if (line.startsWith("event:")) {
event = line.slice("event:".length).trim();
continue;
}
if (!line.startsWith("data:")) continue;
const data = JSON.parse(line.slice("data:".length).trim()) as Record<string, any>;
if (event === "response.output_text.delta") {
const delta = (data.delta as string) || "";
process.stdout.write(delta);
textParts.push(delta);
} else if (event === "response.output_text.done") {
doneParts.push((data.text as string) || "");
} else if (event === "response.completed") {
const final = (data.response as any) || data;
usage = final.usage || null;
} else if (event !== null && event.startsWith("response.")) {
// lifecycle events — ignore
} else {
throw new Error(`Stream terminated by event '${event}': ${JSON.stringify(data)}`);
}
event = null;
}
}
process.stdout.write("\n");
return { text: textParts.join("") || doneParts.join(""), usage };
}
streamResponse("Write a one-paragraph prayer for a new season of ministry.").then(
({ text, usage }) => console.log(`Streamed text (${text.length} chars), usage: ${JSON.stringify(usage)}`)
);
<?php
require_once 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad();
$apiKey = $_ENV['GLOO_API_KEY'] ?? getenv('GLOO_API_KEY') ?: 'YOUR_API_KEY';
$apiUrl = 'https://platform.ai.gloo.com/ai/v2/guarded/responses';
/**
* Process one raw SSE event block (event:/data: lines), mutating $state.
*/
function processEvent(string $rawEvent, array &$state): void {
$event = null;
$data = null;
foreach (preg_split('/\r?\n/', $rawEvent) as $line) {
if (str_starts_with($line, 'event:')) {
$event = trim(substr($line, strlen('event:')));
} elseif (str_starts_with($line, 'data:')) {
$data = json_decode(trim(substr($line, strlen('data:'))), true);
}
}
if ($event === 'response.output_text.delta') {
$delta = $data['delta'] ?? '';
echo $delta;
$state['text_parts'][] = $delta;
} elseif ($event === 'response.output_text.done') {
$state['done_parts'][] = $data['text'] ?? '';
} elseif ($event === 'response.completed') {
// Flattened payload: usage is at the top level; no output[] array.
$final = $data['response'] ?? $data;
$state['usage'] = $final['usage'] ?? null;
} elseif ($event !== null && str_starts_with($event, 'response.')) {
// lifecycle events — ignore
} else {
throw new RuntimeException("Stream terminated by event '{$event}': " . json_encode($data));
}
}
function streamResponse(string $message): array {
global $apiKey, $apiUrl;
$payload = json_encode([
'model' => 'gloo-anthropic-claude-sonnet-4.6',
'input' => $message,
'stream' => true,
'max_output_tokens' => 256,
]);
$state = ['buffer' => '', 'text_parts' => [], 'done_parts' => [], 'usage' => null];
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
'Accept: text/event-stream',
],
CURLOPT_WRITEFUNCTION => function ($ch, string $chunk) use (&$state): int {
$state['buffer'] .= $chunk;
// SSE events are separated by blank lines; process every complete event.
while (($pos = strpos($state['buffer'], "\n\n")) !== false) {
$rawEvent = substr($state['buffer'], 0, $pos);
$state['buffer'] = substr($state['buffer'], $pos + 2);
processEvent($rawEvent, $state);
}
return strlen($chunk);
},
]);
curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
throw new RuntimeException('API request failed: ' . $error);
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException('API request failed with status ' . $status);
}
// Flush any final event not terminated by a blank line.
if (trim($state['buffer']) !== '') {
processEvent($state['buffer'], $state);
}
echo PHP_EOL;
$text = implode('', $state['text_parts']) ?: implode('', $state['done_parts']);
return [$text, $state['usage']];
}
[$text, $usage] = streamResponse('Write a one-paragraph prayer for a new season of ministry.');
echo 'Streamed text (' . mb_strlen($text) . " chars), usage: " . json_encode($usage) . "\n";
?>
package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strings"
)
const apiURL = "https://platform.ai.gloo.com/ai/v2/guarded/responses"
// streamResponse streams via SSE; returns accumulated text and usage.
//
// Each data: payload is the flattened event object itself; lifecycle
// events are ignored, and response.completed carries usage but no output[].
func streamResponse(message string) (string, map[string]interface{}, error) {
payload := map[string]interface{}{
"model": "gloo-anthropic-claude-sonnet-4.6",
"input": message,
"stream": true,
"max_output_tokens": 256,
}
body, _ := json.Marshal(payload)
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(body))
if err != nil {
return "", nil, err
}
req.Header.Add("Authorization", "Bearer "+os.Getenv("GLOO_API_KEY"))
req.Header.Add("Content-Type", "application/json")
req.Header.Set("Accept", "text/event-stream")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
respBody, _ := io.ReadAll(resp.Body)
return "", nil, fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(respBody))
}
var textParts, doneParts []string
var usage map[string]interface{}
event := ""
scanner := bufio.NewScanner(resp.Body)
scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024)
for scanner.Scan() {
line := scanner.Text()
switch {
case strings.HasPrefix(line, "event:"):
event = strings.TrimSpace(line[len("event:"):])
continue
case !strings.HasPrefix(line, "data:"):
continue
}
var data map[string]interface{}
if err := json.Unmarshal([]byte(strings.TrimSpace(line[len("data:"):])), &data); err != nil {
return "", nil, fmt.Errorf("failed to parse SSE data: %w", err)
}
switch {
case event == "response.output_text.delta":
delta, _ := data["delta"].(string)
fmt.Print(delta)
textParts = append(textParts, delta)
case event == "response.output_text.done":
text, _ := data["text"].(string)
doneParts = append(doneParts, text)
case event == "response.completed":
final, ok := data["response"].(map[string]interface{})
if !ok {
final = data // flattened payload
}
if u, ok := final["usage"].(map[string]interface{}); ok {
usage = u
}
case strings.HasPrefix(event, "response."):
// lifecycle events — ignore
default:
dataJSON, _ := json.Marshal(data)
return "", nil, fmt.Errorf("stream terminated by event '%s': %s", event, string(dataJSON))
}
event = ""
}
fmt.Println()
text := strings.Join(textParts, "")
if text == "" {
text = strings.Join(doneParts, "")
}
return text, usage, nil
}
func main() {
text, usage, err := streamResponse("Write a one-paragraph prayer for a new season of ministry.")
if err != nil {
fmt.Println("Error:", err)
return
}
usageJSON, _ := json.Marshal(usage)
fmt.Printf("Streamed text (%d chars), usage: %s\n", len([]rune(text)), string(usageJSON))
}
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class StreamResponse {
private static final String API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
private static final String API_KEY = System.getenv().getOrDefault("GLOO_API_KEY", "YOUR_API_KEY");
private static final Gson gson = new Gson();
public static Map<String, Object> streamResponse(String message) throws Exception {
Map<String, Object> payload = new HashMap<>();
payload.put("model", "gloo-anthropic-claude-sonnet-4.6");
payload.put("input", message);
payload.put("stream", true);
payload.put("max_output_tokens", 256);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + API_KEY)
.header("Accept", "text/event-stream")
.POST(HttpRequest.BodyPublishers.ofString(gson.toJson(payload)))
.build();
HttpResponse<java.io.InputStream> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofInputStream());
if (response.statusCode() != 200) {
String body = new String(response.body().readAllBytes(), StandardCharsets.UTF_8);
throw new IOException("API request failed with status " + response.statusCode() + ": " + body);
}
StringBuilder textBuilder = new StringBuilder();
StringBuilder doneBuilder = new StringBuilder();
JsonElement usage = null;
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(response.body(), StandardCharsets.UTF_8))) {
String event = null;
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("event:")) {
event = line.substring("event:".length()).trim();
continue;
}
if (!line.startsWith("data:")) {
continue;
}
JsonObject data = JsonParser.parseString(line.substring("data:".length()).trim()).getAsJsonObject();
if ("response.output_text.delta".equals(event)) {
String delta = data.has("delta") && !data.get("delta").isJsonNull()
? data.get("delta").getAsString() : "";
System.out.print(delta);
textBuilder.append(delta);
} else if ("response.output_text.done".equals(event)) {
String text = data.has("text") && !data.get("text").isJsonNull()
? data.get("text").getAsString() : "";
doneBuilder.append(text);
} else if ("response.completed".equals(event)) {
// Flattened payload: usage is at the top level; no output[] array.
JsonObject finalResponse = data.has("response") && data.get("response").isJsonObject()
? data.getAsJsonObject("response")
: data;
usage = finalResponse.get("usage");
} else if (event != null && event.startsWith("response.")) {
// lifecycle events — ignore
} else {
throw new IOException("Stream terminated by event '" + event + "': " + gson.toJson(data));
}
event = null;
}
}
System.out.println();
String text = textBuilder.length() > 0 ? textBuilder.toString() : doneBuilder.toString();
Map<String, Object> result = new HashMap<>();
result.put("text", text);
result.put("usage", usage);
return result;
}
public static void main(String[] args) throws Exception {
Map<String, Object> result = streamResponse("Write a one-paragraph prayer for a new season of ministry.");
System.out.println("Streamed text (" + ((String) result.get("text")).length()
+ " chars), usage: " + gson.toJson(result.get("usage")));
}
}
Understanding the Response
When you set"stream": true, the API response is an SSE stream. Here are the key event types, and what to do with each:
| Event Type | When | What to do |
|---|---|---|
response.created | Once — stream start | Nothing required — the stream is open. |
response.output_text.delta | Many — as tokens are generated | Print or buffer each delta as it arrives. |
response.output_text.done | Once per message item | Optionally capture text — the item’s complete text. |
response.completed | Once — stream end | Read usage, then close the stream. |
response.in_progressresponse.output_item.added / doneresponse.content_part.added / done | Interleaved throughout | Ignore — they’re purely structural. |
error.* (or any event you don’t recognize) | Terminal — ends the stream | Treat as an error: close the stream and surface the message. |
event: line followed by a data: line:
event: response.created
data: {"type":"response.created","id":"resp_a1b2c3","object":"response",...}
event: response.output_text.delta
data: {"type":"response.output_text.delta","item_id":"msg_...","delta":"Grief "}
event: response.output_text.done
data: {"type":"response.output_text.done","item_id":"msg_...","text":"Grief support starts..."}
event: response.completed
data: {"type":"response.completed","id":"resp_a1b2c3",...,"usage":{"input_tokens":24,"output_tokens":38,"total_tokens":62}}
The live API sends flattened payloads: each
data: line is the event object itself (its type matches the event: line), with no nested response wrapper. The response.completed payload carries usage at the top level and does not include the output[] array — the full text arrives via response.output_text.done. The snippets below accept both the flattened shape and the nested shape so they work with either.What You’ll See
When you run the full sample, the deltas print live as they arrive. After the stream completes, the runner prints the model, the streamed-text length with a preview, and the usage fromresponse.completed:
Example 3: Streaming (SSE)
Testing: Write a one-paragraph prayer for a new season of ministry.
Lord, as this new season begins, we ask for Your guidance... (deltas print live as they arrive)
Model used: gloo-anthropic-claude-sonnet-4.6
Streamed text (273 chars): Lord, as this new season begins, we ask for Your guidance...
Usage: {"input_tokens": 21, "output_tokens": 74, "total_tokens": 95}
✓ Example 3 passed
Streams can fail after the response has started — a dropped connection mid-stream means partial output. See Handling Streaming Failures for retry, continuation, and partial-output guidance.
Example 4: Vision (Image Input)
Vision uses the same endpoint — pass typed content parts (input_text + input_image) in the content of an input item. Use a vision-capable model such as gloo-google-gemini-3.1-pro:
import os
import requests
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("GLOO_API_KEY", "YOUR_API_KEY")
API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses"
def make_vision_response(image_url, question):
"""Example 4: Vision — image input via typed content parts."""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
payload = {
"model": "gloo-google-gemini-3.1-pro",
"input": [
{
"role": "user",
"content": [
{"type": "input_text", "text": question},
{"type": "input_image", "image_url": image_url},
],
}
],
"max_output_tokens": 256,
}
response = requests.post(API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
result = make_vision_response(
"https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg",
"What animal is in this image?",
)
print(result)
require("dotenv").config();
const API_KEY = process.env.GLOO_API_KEY || "YOUR_API_KEY";
const API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
async function makeVisionResponse(imageUrl, question) {
const payload = {
model: "gloo-google-gemini-3.1-pro",
input: [
{
role: "user",
content: [
{ type: "input_text", text: question },
{ type: "input_image", image_url: imageUrl },
],
},
],
max_output_tokens: 256,
};
const response = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}: ${await response.text()}`);
}
return response.json();
}
makeVisionResponse(
"https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg",
"What animal is in this image?"
).then(console.log);
import { config } from "dotenv";
config();
const API_KEY = process.env.GLOO_API_KEY || "YOUR_API_KEY";
const API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
async function makeVisionResponse(imageUrl: string, question: string): Promise<any> {
const payload = {
model: "gloo-google-gemini-3.1-pro",
input: [
{
role: "user",
content: [
{ type: "input_text", text: question },
{ type: "input_image", image_url: imageUrl },
],
},
],
max_output_tokens: 256,
};
const response = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}: ${await response.text()}`);
}
return response.json();
}
makeVisionResponse(
"https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg",
"What animal is in this image?"
).then(console.log);
<?php
require_once 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad();
$apiKey = $_ENV['GLOO_API_KEY'] ?? getenv('GLOO_API_KEY') ?: 'YOUR_API_KEY';
$apiUrl = 'https://platform.ai.gloo.com/ai/v2/guarded/responses';
function makeVisionResponse(string $imageUrl, string $question): array {
global $apiKey, $apiUrl;
$payload = json_encode([
'model' => 'gloo-google-gemini-3.1-pro',
'input' => [
[
'role' => 'user',
'content' => [
['type' => 'input_text', 'text' => $question],
['type' => 'input_image', 'image_url' => $imageUrl],
],
],
],
'max_output_tokens' => 256,
]);
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
throw new RuntimeException('API request failed: ' . $error);
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException('API request failed with status ' . $status . ': ' . $body);
}
return json_decode($body, true);
}
print_r(makeVisionResponse(
'https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg',
'What animal is in this image?'
));
?>
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
const apiURL = "https://platform.ai.gloo.com/ai/v2/guarded/responses"
func makeVisionResponse(imageURL, question string) (map[string]interface{}, error) {
payload := map[string]interface{}{
"model": "gloo-google-gemini-3.1-pro",
"input": []map[string]interface{}{
{
"role": "user",
"content": []map[string]interface{}{
{"type": "input_text", "text": question},
{"type": "input_image", "image_url": imageURL},
},
},
},
"max_output_tokens": 256,
}
body, _ := json.Marshal(payload)
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(body))
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+os.Getenv("GLOO_API_KEY"))
req.Header.Add("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(respBody))
}
var result map[string]interface{}
json.Unmarshal(respBody, &result)
return result, nil
}
func main() {
result, err := makeVisionResponse(
"https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg",
"What animal is in this image?",
)
if err != nil {
fmt.Println("Error:", err)
return
}
out, _ := json.MarshalIndent(result, "", " ")
fmt.Println(string(out))
}
import com.google.gson.Gson;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class VisionResponse {
private static final String API_URL = "https://platform.ai.gloo.com/ai/v2/guarded/responses";
private static final String API_KEY = System.getenv().getOrDefault("GLOO_API_KEY", "YOUR_API_KEY");
private static final Gson gson = new Gson();
public static Map<String, Object> makeVisionResponse(String imageUrl, String question) throws Exception {
Map<String, Object> textPart = new HashMap<>();
textPart.put("type", "input_text");
textPart.put("text", question);
Map<String, Object> imagePart = new HashMap<>();
imagePart.put("type", "input_image");
imagePart.put("image_url", imageUrl);
Map<String, Object> inputItem = new HashMap<>();
inputItem.put("role", "user");
inputItem.put("content", List.of(textPart, imagePart));
Map<String, Object> payload = new HashMap<>();
payload.put("model", "gloo-google-gemini-3.1-pro");
payload.put("input", List.of(inputItem));
payload.put("max_output_tokens", 256);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + API_KEY)
.POST(HttpRequest.BodyPublishers.ofString(gson.toJson(payload)))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("API request failed with status " + response.statusCode() + ": " + response.body());
}
return gson.fromJson(response.body(), Map.class);
}
public static void main(String[] args) throws Exception {
Map<String, Object> result = makeVisionResponse(
"https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg",
"What animal is in this image?");
System.out.println(gson.toJson(result));
}
}
What You’ll See
The reply arrives as a normalmessage item in output[] — for the cat photo above, the answer identifies the animal:
{
"id": "resp_...",
"object": "response",
"model": "gloo-google-gemini-3.1-pro",
"output": [
{
"type": "message",
"role": "assistant",
"content": [
{ "type": "output_text", "text": "The animal in this image is a cat." }
]
}
],
"usage": { "input_tokens": 275, "output_tokens": 9, "total_tokens": 284 }
}
Example 4: Vision (Image Input)
Testing: https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg
Model used: gloo-google-gemini-3.1-pro
Response: The animal in this image is a cat.
Usage: {"input_tokens": 275, "output_tokens": 9, "total_tokens": 284}
✓ Example 4 passed
Complete Example
View Complete Code
Clone or browse the complete working examples for all 6 languages (JavaScript, TypeScript, Python, PHP, Go, Java) with setup instructions.
What’s Included
Each language implementation provides:auth— Shared API key configurationconfig— Centralized configuration (endpoint, env vars)- Runner per example — Basic guarded response, instructions + multi-turn, streaming, and vision, plus a final banner
- Env helper — Ignores unset
.envplaceholders posthelper — Shared request helper that annotates 403s with “(guardrails hard-blocked this request)”extractTexthelper — Reusable helper for pulling text out ofoutput[]
# Create a .env file in the language directory (or export for Go/Java)
GLOO_API_KEY=your_actual_api_key_here
cd responses/python
pip install -r requirements.txt
python main.py
cd responses/javascript
npm install && npm start
cd responses/typescript
npm install && npx tsx index.ts
cd responses/php
composer install && php index.php
cd responses/go
go mod tidy && go run main.go
cd responses/java
mvn compile && mvn exec:java
=== All Responses API tests passed! ===
The snippets in this tutorial are simplified to be self-contained. The cookbook samples are structured the same way but add robustness: an env helper that ignores unset
.env placeholders, a shared post helper that annotates 403s with “(guardrails hard-blocked this request)”, and a reusable extractText helper for pulling text out of output[]. The prompts, field names, and endpoint are identical.Troubleshooting
Please set your GLOO_API_KEY environment variable
: Your .env file is missing or doesn’t contain GLOO_API_KEY. Create one in the language’s directory (see Complete Example), or export the variable in your shell for Go and Java.
API request failed with status 403
: Guardrails hard-blocked the request. The 403 body includes a content_policy_violation detail — rephrase the request rather than retrying. See Guardrail behavior.
Vision request returns 400 / INVALID_REQUEST
: The model isn’t vision-capable. Vision requires a multimodal model like gloo-google-gemini-3.1-pro — sending image parts to a text-only model (e.g. gloo-anthropic-claude-sonnet-4.6) fails. Check Supported Models for capabilities.
Vision request fails on image fetch
: The API fetches image_url server-side, so the URL must be publicly reachable. Test it in a browser or curl -I <url>. Private or expiring URLs fail; use a public URL or a base64 data: URI.
Stream parses nothing, or every event looks unknown
: Remember the payloads are flattened — the data: line is the event object itself, not { "response": {...} }. Match on the event: line, handle response.output_text.delta/done and response.completed, and ignore other response.* lifecycle events. Treating unknown events as terminal (and closing the stream) is the safe default.
Next Steps
Now that you understand the Responses API, explore:- Responses API Guide - Full API documentation
- Tool Use - Function calling with Responses
- Grounded Responses - RAG with source attribution
- Direct Responses - Unguarded direct endpoint
- Completions V2 Guide - Auto-routing and
model_familyselection - Supported Model IDs - All available models

