Public preview — This API is in public preview. Endpoints, schemas, and limits may change before general availability.
API
Your first request
Step-by-step walkthroughs in curl, JavaScript, and Python — and how to read each response.
This guide walks through one complete request end-to-end, in three languages. You will set up the environment, send the request, and parse the response.
Setup#
You need:
- An EU GPT API key (see Authentication).
- The key exported as
EUGPT_API_KEYso the snippets below pick it up without inlining it.
export EUGPT_API_KEY="eugpt_..."
Non-streaming: ask one question, get one answer#
The simplest possible request. stream: false returns one JSON document; no SSE parsing required.
curl https://chat.eugpt.ai/v1/responses \
-H "Authorization: Bearer $EUGPT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"input": "Explain the EU AI Act in three short bullets.",
"stream": false
}'import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.EUGPT_API_KEY,
baseURL: "https://chat.eugpt.ai/v1",
});
const response = await client.responses.create({
model: "auto",
input: "Explain the EU AI Act in three short bullets.",
stream: false,
});
console.log(response.output_text);import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["EUGPT_API_KEY"],
base_url="https://chat.eugpt.ai/v1",
)
response = client.responses.create(
model="auto",
input="Explain the EU AI Act in three short bullets.",
stream=False,
)
print(response.output_text) The shape of the JSON body is documented in Create a response.
Streaming: render output as it arrives#
For anything user-facing, stream. The first text chunks arrive within a few hundred milliseconds, even when the full response takes a few seconds.
curl -N https://chat.eugpt.ai/v1/responses \
-H "Authorization: Bearer $EUGPT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"input": "Write a long-form explanation of data sovereignty."
}'const stream = await client.responses.create({
model: "auto",
input: "Write a long-form explanation of data sovereignty.",
stream: true,
});
for await (const event of stream) {
if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
} else if (event.type === "response.completed") {
process.stdout.write("\n");
}
}stream = client.responses.create(
model="auto",
input="Write a long-form explanation of data sovereignty.",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
elif event.type == "response.completed":
print() Adding a system prompt#
instructions steers tone, format, and persona for this response.
const response = await client.responses.create({
model: "auto",
input: "Summarise the GDPR.",
instructions: "Respond in Dutch. Use exactly five bullet points.",
stream: false,
});
If you also pass a brand-new conversation_id, the instructions are stored as the conversation’s system message and apply to every subsequent turn.
Continuing the conversation#
Capture the conversation id and pass it on the next call. (The conversation id is returned on every response — for stateless requests it identifies the ephemeral, hidden conversation that was created.)
const first = await client.responses.create({
model: "auto",
input: "Plan a sprint to migrate from Chat Completions.",
});
const conversationId = first.conversation_id;
const followUp = await client.responses.create({
model: "auto",
conversation_id: conversationId,
input: "Now expand step 3 into substeps.",
});
Error handling#
Always check for the error envelope. Status codes you should plan for: 400, 401, 403, 429, 5xx. See Errors for retry guidance.
try {
const response = await client.responses.create({ /* … */ });
return response.output_text;
} catch (err) {
if (err.status === 429) {
// Quota hit. Back off, upgrade plan, or queue.
} else if (err.status >= 500) {
// Transient. Retry with exponential backoff.
} else {
// Something the user did. Surface to caller.
throw err;
}
}
Next steps#
- Handling streams — parsing without an SDK, custom event handling.
- Tool use — what to do when the model decides to call
web_search.