# The APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →: your first real calls
The fastest way to outgrow the ChatGPT window is to make the same model answer from inside your own code, and with OpenAI that takes about ten lines. This lesson is about those ten lines: what is OpenAI-specific, why the Responses APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → is now the default, and how to stream tokens as they arrive.
Get a key from the API keys page. Treat it like a password: it is tied to billing, and anyone holding it can spend your credits. Never paste it into code or commit it to git.
Set it as an environment variable so the SDK finds it automatically:
export OPENAI_API_KEY="sk-proj-..."
pip install openaiThe official Python SDK reads OPENAI_API_KEY on its own, so you never write the key in your script. One important boundary: your APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → account and your ChatGPT subscription are separate. ChatGPT Plus or Pro does not give you APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → credits, and APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → usage is billed per tokentokenA token is the basic unit of text that language models process, often a word fragment, whole word, or punctuation mark rather than a single character.Voir la définition complète → against a different balance. They share models, not wallets.
Here is a complete, runnable script using the Responses API, OpenAI's current primary interface:
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4.1-mini",
instructions="You are a terse assistant. Answer in one sentence.",
input="Explain what an idempotent API request is.",
)
print(response.output_text)Run it and you get a single clean sentence back. Now let's unpack the parts that are specific to OpenAI.
client = OpenAI()This builds the client and silently picks up your environment key. Everything you do flows through this object: text generation, embeddings, files, audio. You configure it once.
model="gpt-4.1-mini"The model string is a real, billable choice, not a label. OpenAI ships several families: the GPT-4.1 line for general-purpose work, the smaller mini and nano variants for cheaper and faster calls, and the reasoning models (the o-series, like o4-mini) that think longer before answering. Pick by job. A classifier or a formatter wants mini or nano. A multi-step planning task wants a reasoning model. Check the current roster and pricing on the models page, because the lineup shifts.
instructions vs inputThis is the cleanest improvement the Responses APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → brings. instructions is the system-level steering (personapersonaA semi-fictional, research-based representation of your ideal customer: their goals, frustrations, behaviours and decision criteria.Voir la définition complète →, rules, output format). input is the actual user turn. You no longer hand-build a list of role-tagged message dictionaries for simple calls. For a single exchange, two strings is all you need.
response.output_textA convenience accessor that flattens the response into the final text string. The full response object carries more: tokentokenA token is the basic unit of text that language models process, often a word fragment, whole word, or punctuation mark rather than a single character.Voir la définition complète → usage, the model that actually served you, tool calls, and structured content blocks. For quick work, output_text is what you want; for production, you will read the richer fields.
You will see both in tutorials, so know the difference.
Chat Completions (client.chat.completions.create) is the older, widely-copied interface. It takes a messages list of {"role": ..., "content": ...} dicts. It still works and is not deprecated, so existing code is safe.
Responses (client.responses.create) is what OpenAI now recommends for new projects. It is stateful-friendly, has built-in tools (web search, file search, code interpreter) you can switch on without wiring them yourself, and it handles multi-step tool use more cleanly. The Responses API docs are the canonical reference.
Rule of thumb: new code, start with Responses. Only reachreachThe number of unique people exposed to your message in a given period. Unlike impressions, reach counts each person once, no matter how often they see it.Voir la définition complète → for Chat Completions if you are extending something that already uses it.
Waiting for a long answer to fully generate before showing anything feels broken to users. Streaming sends tokenstokensA token is the basic unit of text that language models process, often a word fragment, whole word, or punctuation mark rather than a single character.Voir la définition complète → as the model produces them, which is exactly the typewriter effect you see in ChatGPT.
You opt in with stream=True and iterate over events:
from openai import OpenAI
client = OpenAI()
stream = client.responses.create(
model="gpt-4.1-mini",
input="Write a two-line haiku about slow APIs.",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
print()The stream yields typed events, not just raw text. You filter for response.output_text.delta to catch the incremental text chunks. Other event types announce when the response starts, when a tool is called, and when generation completes. The flush=True forces each chunk to the terminal immediately instead of buffering.
Streaming changes nothing about cost or the final result. It only changes *when* you see the bytes. Use it for any user-facing interface; skip it for batch jobs where nobody is watching.
When you need the model to return data your code can parse, do not beg it for JSON in the prompt and hope. Use Structured Outputs, which forces the response to match a schemaschemaA schema is the formal blueprint that defines how data is structured, named, typed, and related within a database, file, or message.Voir la définition complète → you define. You pass a JSON SchemaSchemaA schema is the formal blueprint that defines how data is structured, named, typed, and related within a database, file, or message.Voir la définition complète → (or a Pydantic model in Python) and OpenAI guarantees the shape, so you never write defensive parsing for a stray markdown fence again.
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI()
class Ticket(BaseModel):
priority: str
summary: str
response = client.responses.parse(
model="gpt-4.1-mini",
input="My checkout button has been broken for two days, losing sales.",
text_format=Ticket,
)
ticket = response.output_parsed
print(ticket.priority, "|", ticket.summary)response.output_parsed hands you a typed Ticket object. This is the single biggest reliability upgrade for anyone building real features. The Structured Outputs guide covers the schemaschemaA schema is the formal blueprint that defines how data is structured, named, typed, and related within a database, file, or message.Voir la définition complète → rules.
The model can decide to call functions you expose, returning the function name and arguments for you to execute. You describe your functions, the model picks one when relevant, you run it, then you feed the result back. This is the primitive under tool-using assistants. Note the boundary: the APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →'s function calling is not the same as GPT Actions in Custom GPTs. Actions are the no-code version inside the ChatGPT product; function calling is the raw mechanism you control in code.
When one function call becomes a loop of planning, calling tools, and checking results, you graduate to the Agents SDK. It is OpenAI's official framework for multi-step agents: it manages the tool-call loop, handoffs between specialized agents, and guardrails, so you do not hand-roll the orchestration. You do not need it for your first calls, but it is the natural next step once a single Responses call is not enough. It builds directly on top of the Responses APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →.
Vérification des acquis
1. According to the lesson, what is the relationship between a ChatGPT Plus/Pro subscription and API credits?
2. How does the official Python SDK obtain your API key in the lesson's setup?
3. In the OpenAI model lineup described, what is the purpose of the 'mini' and 'nano' variants?
4. Select ALL correct answers about handling the OpenAI API key safely, per the lesson.
Sélectionnez toutes les réponses correctes.
5. Select ALL correct answers about the Responses API example shown in the lesson.
Sélectionnez toutes les réponses correctes.
For anything beyond a demo, stop printing output_text and start inspecting the whole object. Two fields matter immediately.
Usage. Every response reports tokentokenA token is the basic unit of text that language models process, often a word fragment, whole word, or punctuation mark rather than a single character.Voir la définition complète → counts:
print(response.usage.input_tokens, response.usage.output_tokens)This is how you measure cost. Input tokenstokensA token is the basic unit of text that language models process, often a word fragment, whole word, or punctuation mark rather than a single character.Voir la définition complète → (your prompt and instructions) and output tokenstokensA token is the basic unit of text that language models process, often a word fragment, whole word, or punctuation mark rather than a single character.Voir la définition complète → (the generation) are priced differently, and output is usually the more expensive side. Logging usage from day one saves you from a surprise bill later.
The served model. The model field tells you which exact model version answered. When you pin a dated snapshot versus an alias that auto-updates, this field is how you confirm what ran. For reproducible production behavior, pin a specific snapshot rather than a floating alias.
Real calls fail for real reasons. Handle the common ones explicitly:
from openai import OpenAI, RateLimitError, APIError
client = OpenAI()
try:
response = client.responses.create(
model="gpt-4.1-mini",
input="Summarize the API economy in one line.",
)
print(response.output_text)
except RateLimitError:
print("Slow down or upgrade your tier, then retry with backoff.")
except APIError as err:
print(f"OpenAI-side issue: {err}")RateLimitError is the one beginners meet first. New APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → accounts start on a low usage tier with modest per-minute limits; tiers rise automatically as your account ages and you spend. Do not treat a rate limit as a bug. Treat it as a signal to add retry-with-backoff, which the SDK can do for you via the max_retries setting on the client. APIError and its subclasses cover authentication, bad requests, and transient server errors. Catch them so one hiccup does not crash your app.
A few habits pay off immediately:
max_output_tokens so a chatty model cannot run long and run up the bill. A summarizer rarely needs more than a couple hundred tokenstokensA token is the basic unit of text that language models process, often a word fragment, whole word, or punctuation mark rather than a single character.Voir la définition complète →.mini or nano and reserve the heavy or reasoning models for tasks that genuinely need them.These three levers (output cap, model choice, concurrency) cover most of the cost and latency tuning you will do early on.
client.responses.create) with instructions and input; keep Chat Completions only for existing codebases.max_output_tokens so cost stays visible and bounded.response.output_text.delta events, and catch RateLimitError with backoff rather than letting it crash your app.