Learn › GPT-6 Astra in Practice › The Responses API: Foundation for Serious Work

The Responses API: Foundation for Serious Work

Intermediate 🕐 16 min Lesson 9 of 15
What you'll learn
  • Make a working Responses API call with gpt-6-astra
  • Know when to use Responses API versus Chat Completions
  • Migrate a simple Chat Completions app to Responses API

Why Responses API Is Now the Default

Three capabilities in GPT-6 Astra only work through the Responses API: tool calling, computer use, and persisted reasoning across turns. Chat Completions remains valid for bare text generation with no tools attached — if you're sending a prompt and expecting back a string, Chat Completions still works and requires no changes.

But the moment you add tools, the contract changes. Tool calling in Astra passes through client.responses.create(), not client.chat.completions.create(). Computer use — Astra controlling a browser or desktop — is exclusive to the Responses API. Persisted reasoning via previous_response_id, which lets Astra carry its internal reasoning state from one call to the next, is also Responses-only.

The practical rule: if you're building anything beyond a simple prompt-to-string completion, start with the Responses API. Migrating later is possible but means rewriting your request structure and response parsing. Start right.

Two parameter families from Chat Completions are removed in Astra on both APIs: temperature, top_p, and top_logprobs are not accepted. Astra's recurrent depth reasoning controls output diversity internally. Passing those parameters returns a 400 error.

The Request Shape

A minimal Responses API call uses three fields: model, input, and optionally reasoning. Here's the simplest working Python call with no tools:

from openai import OpenAI

client = OpenAI()  # reads OPENAI_API_KEY from env

response = client.responses.create(
    model="gpt-6-astra",
    input="Summarize the key differences between REST and GraphQL."
)

print(response.output_text)

input accepts either a plain string or a messages array. For multi-turn conversations, pass the full message history as a list:

response = client.responses.create(
    model="gpt-6-astra",
    input=[
        {"role": "user", "content": "What is recurrent depth reasoning?"},
        {"role": "assistant", "content": "Recurrent depth reasoning means..."},
        {"role": "user", "content": "How does it differ from chain-of-thought?"}
    ],
    reasoning={"effort": "medium"}
)

To add a built-in tool — here, web search — include a tools array:

response = client.responses.create(
    model="gpt-6-astra",
    input="What are the current OpenAI API rate limits for gpt-6-astra?",
    tools=[{"type": "web_search_preview"}],
    reasoning={"effort": "medium"}
)

print(response.output_text)

The reasoning object takes an effort value: "low", "medium", "high", "xhigh", or "max". Omit it and you get the API default. Use reasoning={"effort": "low"} for fast, cost-effective calls on simple tasks and save higher tiers for work that actually requires them.

The JavaScript SDK follows the same pattern:

import OpenAI from "openai";

const client = new OpenAI();

const response = await client.responses.create({
    model: "gpt-6-astra",
    input: "Explain the Responses API in two sentences.",
    reasoning: { effort: "low" }
});

console.log(response.output_text);

Streaming

Long-running Astra responses — especially those involving tool calls, reasoning at high or above, or multi-step agent loops — can take several minutes. Without streaming, your HTTP connection stays open waiting for the complete response, and a proxy or load balancer timeout kills it before you receive anything. Streaming solves this by sending chunks as they are produced.

Enable it with the SDK's stream() context manager:

with client.responses.stream(
    model="gpt-6-astra",
    input="Walk through the steps of a merge sort algorithm in detail.",
    reasoning={"effort": "high"}
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

stream.text_stream is an iterator over text chunks as they arrive. For event-level access — including tool call output, reasoning summaries, and finish reasons — use the lower-level event iterator:

with client.responses.stream(
    model="gpt-6-astra",
    input="Analyze this document...",
    tools=[{"type": "code_interpreter"}]
) as stream:
    for event in stream:
        if event.type == "response.output_text.delta":
            print(event.delta, end="", flush=True)

Streaming is the right default for production code. It gives users visible progress, prevents silent timeouts, and surfaces errors early in a long response rather than after a full wait. If you're running Astra at medium effort or above, use streaming.

Rate Limits and Access Tiers

GPT-6 Astra has no free API tier. Access requires a paid OpenAI account, and rate limits scale with your usage tier. The table below shows the approximate structure — check your exact caps at platform.openai.com/account/limits.

Tier
Approx. RPM
How to qualify
Tier 1
~10–20 RPM
$5+ in API credits purchased
Tier 2
~50–100 RPM
$50+ spent and 7+ days since first payment
Tier 3+
Higher limits
$100–$250+ spent with sustained usage

When you hit a rate limit, the API returns a 429 RateLimitError. The correct response is exponential backoff with jitter — start at 1 second, double on each failure, cap at 60 seconds. The OpenAI SDK handles this automatically by default; if you're managing retries yourself, replicate that pattern rather than retrying immediately.

For sustained high-throughput use — batch processing, large agent pipelines — contact OpenAI to request a limit increase. Tier promotions happen automatically based on spend, but explicit requests move faster when you're running production workloads.

Migrating from Chat Completions

If you have existing code using client.chat.completions.create(), migration is mostly mechanical. The message format stays the same — roles and content objects work identically. What changes is the method name, the response object shape, and the streaming interface.

Chat Completions
Responses API
client.chat.completions.create()
client.responses.create()
messages=[...]
input=[...] (same object shape)
response.choices[0].message.content
response.output_text
response_format={"type":"json_object"}
text={"format":{"type":"json_object"}}
Stream via chunk.choices[0].delta
Stream via stream.text_stream

The fastest migration path: replace the method call and update the one line where you read the output text. If your app sends a plain prompt and reads back a string with no tools, that's the entire migration. Add reasoning={"effort": "medium"} and you're running Astra.

For apps that use tool calling, the migration is more involved. Chat Completions tool calls return in choices[0].message.tool_calls; the Responses API returns them as typed function_call items in the output array, and your tool results go back as function_call_output items with a matching call_id. Rewrite the tool loop against the new item types — the tool definitions themselves (name, description, parameters as JSON Schema) are unchanged.

Key takeaways
  • The Responses API is required for tool calling, computer use, and persisted reasoning in GPT-6 Astra
  • Chat Completions still works for simple text completions with no tools
  • Model ID is gpt-6-astra — swapping it into existing OpenAI SDK code is the first migration step