Migrating a Terminal Script to the Responses API
Move a terminal script from Chat Completions to Responses
The migration starts with two visible changes: POST /v1/chat/completions becomes POST /v1/responses, and messages becomes input. The important work is updating response parsing, conversation state, and any tool loop around that request. I prefer migrating one small terminal script before touching an application’s shared client.
Fluxo gives that script one key and one base URL, https://api.fluxorelay.com, across Claude, GPT, Gemini, DeepSeek, Kimi, GLM, Qwen, Grok, and more. This walkthrough uses the OpenAI Python SDK and GPT-6 Astra as the model to look for. Model availability does not automatically guarantee Responses support; confirm that the selected route accepts this endpoint before migrating production traffic.
Prepare Bash, Python, and the Fluxo connection
If you need a key for this walkthrough, you can create a Fluxo account. Run these commands in Bash with Python 3, curl, and jq installed. The virtual environment keeps this experiment out of your application’s dependencies.
mkdir -p fluxo-responses-migration && cd fluxo-responses-migration — python3 -m venv .venv
source .venv/bin/activate — python -m pip install --upgrade openai
read -rsp 'Fluxo API key: ' OPENAI_API_KEY; printf '\n'; export OPENAI_API_KEY
export OPENAI_BASE_URL='https://api.fluxorelay.com/v1'
The SDK base URL includes /v1; the SDK appends /responses itself. Do not append /v1 again to individual SDK calls. Keep the key out of source files and committed shell configuration.
Select the returned model ID before changing endpoints
Fetch the model catalog, then inspect its returned IDs. Choose the identifier corresponding to GPT-6 Astra rather than assuming its display name is the API identifier.
curl --fail-with-body --silent --show-error "$OPENAI_BASE_URL/models" -H "Authorization: Bearer $OPENAI_API_KEY" -o models.json
jq '.data[] | {id, name}' models.json — read -rp 'Paste the returned model ID: ' OPENAI_MODEL; export OPENAI_MODEL
Keep that value constant while comparing endpoints. If the route rejects Responses, stop and check endpoint availability instead of interpreting the failure as a prompt-format problem.
Run the Chat Completions baseline
This baseline deliberately avoids streaming and tools. It makes the first comparison about request shape and text extraction, not several moving parts at once.
python -c 'import os; from openai import OpenAI; c = OpenAI(); r = c.chat.completions.create(model=os.environ["OPENAI_MODEL"], messages=[{"role": "system", "content": "Answer concisely."}, {"role": "user", "content": "Explain an HTTP 429 in one sentence."}]); print(r.choices[0].message.content)'
Save the command in your terminal history, but do not expect the next call to produce identical wording. You are testing successful execution and equivalent intent, not deterministic output.
Replace messages with input and read output_text
Move the stable instruction into instructions and the user prompt into input. The SDK’s output_text convenience property collects text output; it replaces choices[0].message.content for this simple case.
python -c 'import os; from openai import OpenAI; c = OpenAI(); r = c.responses.create(model=os.environ["OPENAI_MODEL"], instructions="Answer concisely.", input="Explain an HTTP 429 in one sentence."); print(r.output_text)'
For existing role-based histories, Responses also accepts structured input items. Do not blindly rename every field: output-token limits, tool definitions, tool results, and streaming events need their own migration pass.
- Replace max_tokens with max_output_tokens where the selected route supports it.
- Read structured output items when handling tools, not only output_text.
- Update streaming consumers for Responses events instead of Chat Completions deltas.
- Preserve tool call identifiers when returning execution results to the model.
Check state, errors, and billing before switching traffic
Start with explicitly supplied conversation history. If you later use previous_response_id, verify response storage and continuation support on the relay route first. Resend instructions on subsequent requests; do not assume a previous response identifier carries those instructions forward.
Keep authentication failures, unsupported endpoints, rate limits, and malformed inputs separate in your logs. Record request IDs when available, but redact keys and sensitive prompts. If you need help, leave a note on the contact page after signing in.
Fluxo bills per real token, including cache reads and writes, with no monthly fee. Compare returned usage and actual charges rather than assuming both endpoints consume the same tokens. Its key also works with Claude Code, Codex, Gemini CLI, and any OpenAI SDK, though each client’s endpoint support still matters. Users earn a referral share when people they invite pay.
Once the plain-text smoke test passes, migrate streaming and tools separately, then switch traffic behind a reversible configuration flag.