Toolmingo
Guides12 min read

OpenAI API Cheat Sheet: The Complete Quick Reference

A complete OpenAI API cheat sheet — chat completions, streaming, function calling, structured outputs, embeddings, vision, image generation, audio, and error handling.

The OpenAI API patterns you need every day — chat completions, streaming, function calling, structured outputs, embeddings, vision, audio, and error handling — with copy-ready code.

Quick reference

Task Code
Install pip install openai
Set API key (env) export OPENAI_API_KEY="sk-..."
Chat completion client.chat.completions.create(model="gpt-4o", messages=[...])
Get text response.choices[0].message.content
Stream response stream=True + for chunk in stream
JSON output response_format={"type": "json_object"}
Structured output response_format=MyPydanticModel (beta.parse)
Function calling tools=[{"type": "function", "function": {...}}]
Embeddings client.embeddings.create(model="text-embedding-3-small", input="...")
Image input Pass {"type": "image_url", "image_url": {"url": "..."}} in messages
DALL-E image client.images.generate(model="dall-e-3", prompt="...")
Whisper transcribe client.audio.transcriptions.create(model="whisper-1", file=f)
TTS audio client.audio.speech.create(model="tts-1", voice="alloy", input="...")
Token count tiktoken.encoding_for_model("gpt-4o").encode(text)
Async client from openai import AsyncOpenAI

Setup

pip install openai tiktoken
from openai import OpenAI
import os

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# Or: OpenAI() auto-reads OPENAI_API_KEY from environment

Chat completions

Basic request:

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is the capital of France?"},
    ],
    max_tokens=256,
    temperature=0.7,
)

text = response.choices[0].message.content
print(text)
# Token usage
print(response.usage.prompt_tokens, response.usage.completion_tokens)

Multi-turn conversation (keep history manually):

messages = [{"role": "system", "content": "You are a concise assistant."}]

def chat(user_input):
    messages.append({"role": "user", "content": user_input})
    response = client.chat.completions.create(model="gpt-4o", messages=messages)
    reply = response.choices[0].message.content
    messages.append({"role": "assistant", "content": reply})
    return reply

print(chat("Hello! My name is Alice."))
print(chat("What is my name?"))   # Model remembers "Alice"

Key parameters

Parameter Default Description
model required Model ID (see models table)
messages required List of {role, content} dicts
max_tokens model max Max tokens to generate
temperature 1.0 Randomness 0–2 (0 = deterministic)
top_p 1.0 Nucleus sampling (use instead of temperature)
n 1 Number of choices to generate
stop None Stop sequences (str or list)
stream False Enable streaming
seed None Reproducible outputs (best-effort)
logprobs False Return log probabilities
presence_penalty 0 Penalise new topics −2–2
frequency_penalty 0 Penalise repetition −2–2

Streaming

stream = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Tell me a joke."}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)
print()

Collect full response while streaming:

full_text = ""
for chunk in stream:
    delta = chunk.choices[0].delta.content or ""
    full_text += delta
    print(delta, end="", flush=True)

Structured outputs (JSON)

JSON mode (any valid JSON)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "Return valid JSON only."},
        {"role": "user", "content": "List 3 programming languages with their year created."},
    ],
    response_format={"type": "json_object"},
)

import json
data = json.loads(response.choices[0].message.content)

Structured outputs with Pydantic (guaranteed schema)

from pydantic import BaseModel
from openai import OpenAI

client = OpenAI()

class Language(BaseModel):
    name: str
    year_created: int
    paradigm: str

class LanguageList(BaseModel):
    languages: list[Language]

response = client.beta.chat.completions.parse(
    model="gpt-4o-2024-08-06",
    messages=[
        {"role": "user", "content": "List 3 programming languages."},
    ],
    response_format=LanguageList,
)

result = response.choices[0].message.parsed  # LanguageList instance
for lang in result.languages:
    print(lang.name, lang.year_created)

Function calling (tools)

import json

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "City name"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["city"],
            },
        },
    }
]

messages = [{"role": "user", "content": "What's the weather in Paris?"}]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

message = response.choices[0].message

# Check if model wants to call a function
if message.tool_calls:
    tool_call = message.tool_calls[0]
    args = json.loads(tool_call.function.arguments)
    
    # Execute your actual function
    weather_result = {"temperature": 18, "condition": "sunny"}
    
    # Send result back to model
    messages.append(message)
    messages.append({
        "role": "tool",
        "tool_call_id": tool_call.id,
        "content": json.dumps(weather_result),
    })
    
    final = client.chat.completions.create(model="gpt-4o", messages=messages, tools=tools)
    print(final.choices[0].message.content)

tool_choice options:

Value Behaviour
"auto" Model decides (default)
"none" Never call tools
"required" Always call a tool
{"type": "function", "function": {"name": "fn"}} Force specific function

Embeddings

response = client.embeddings.create(
    model="text-embedding-3-small",
    input="The quick brown fox",
)

vector = response.data[0].embedding  # list of floats
print(len(vector))  # 1536

# Batch multiple texts
response = client.embeddings.create(
    model="text-embedding-3-small",
    input=["Text one", "Text two", "Text three"],
)
vectors = [item.embedding for item in response.data]

Cosine similarity:

import numpy as np

def cosine_similarity(a, b):
    a, b = np.array(a), np.array(b)
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

sim = cosine_similarity(vectors[0], vectors[1])
print(f"Similarity: {sim:.4f}")

Embedding models

Model Dimensions Max tokens Best for
text-embedding-3-small 1536 8191 Cost-efficient RAG
text-embedding-3-large 3072 8191 Highest accuracy
text-embedding-ada-002 1536 8191 Legacy (use 3-small)

Vision (image input)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What's in this image?"},
                {
                    "type": "image_url",
                    "image_url": {"url": "https://example.com/photo.jpg"},
                },
            ],
        }
    ],
)
print(response.choices[0].message.content)

Base64 local image:

import base64

with open("image.png", "rb") as f:
    b64 = base64.standard_b64encode(f.read()).decode()

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Describe this image."},
                {
                    "type": "image_url",
                    "image_url": {"url": f"data:image/png;base64,{b64}"},
                },
            ],
        }
    ],
)

detail level for image tokens:

Detail Tokens Use when
"low" 85 Fast, cheap, no detail needed
"high" 85 + 170/tile Fine detail required
"auto" Automatic Default
"image_url": {"url": "https://...", "detail": "low"}

Image generation (DALL-E)

response = client.images.generate(
    model="dall-e-3",
    prompt="A futuristic cityscape at sunset, digital art",
    size="1024x1024",
    quality="standard",
    n=1,
)

image_url = response.data[0].url
revised_prompt = response.data[0].revised_prompt  # DALL-E 3 auto-revises
print(image_url)

Image editing (DALL-E 2):

with open("image.png", "rb") as img, open("mask.png", "rb") as mask:
    response = client.images.edit(
        image=img,
        mask=mask,
        prompt="Add a rainbow in the sky",
        n=1,
        size="1024x1024",
    )
Model Sizes Max n Best for
dall-e-3 1024×1024, 1792×1024, 1024×1792 1 Quality, prompt following
dall-e-2 256×256 to 1024×1024 10 Edits, variations, cost

Audio

Transcription (Whisper)

with open("audio.mp3", "rb") as f:
    transcript = client.audio.transcriptions.create(
        model="whisper-1",
        file=f,
        language="en",          # Optional: ISO 639-1 code
        response_format="text", # "text" | "json" | "verbose_json" | "srt" | "vtt"
    )
print(transcript.text)

# With timestamps (verbose_json)
with open("audio.mp3", "rb") as f:
    result = client.audio.transcriptions.create(
        model="whisper-1",
        file=f,
        response_format="verbose_json",
        timestamp_granularities=["word"],
    )
for word in result.words:
    print(f"{word.word}: {word.start:.2f}s–{word.end:.2f}s")

Translation (to English)

with open("french_audio.mp3", "rb") as f:
    result = client.audio.translations.create(
        model="whisper-1",
        file=f,
    )
print(result.text)  # Always English output

Text-to-speech (TTS)

response = client.audio.speech.create(
    model="tts-1",          # or "tts-1-hd" for higher quality
    voice="alloy",
    input="Hello, world! This is a test of the OpenAI TTS API.",
    speed=1.0,              # 0.25–4.0
    response_format="mp3",  # mp3 | opus | aac | flac | wav | pcm
)

with open("output.mp3", "wb") as f:
    f.write(response.content)

Available voices: alloy, echo, fable, onyx, nova, shimmer

Async client

import asyncio
from openai import AsyncOpenAI

client = AsyncOpenAI()

async def get_completion(prompt: str) -> str:
    response = await client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}],
    )
    return response.choices[0].message.content

# Run multiple requests concurrently
async def main():
    prompts = ["Explain BFS", "Explain DFS", "Explain Dijkstra"]
    results = await asyncio.gather(*[get_completion(p) for p in prompts])
    for r in results:
        print(r[:100])

asyncio.run(main())

Error handling

from openai import (
    OpenAI,
    APIConnectionError,
    RateLimitError,
    APIStatusError,
    AuthenticationError,
    BadRequestError,
)
import time

client = OpenAI()

def call_with_retry(messages, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model="gpt-4o",
                messages=messages,
            )
        except RateLimitError:
            wait = 2 ** attempt
            print(f"Rate limited. Retrying in {wait}s...")
            time.sleep(wait)
        except APIConnectionError as e:
            print(f"Connection error: {e}")
            time.sleep(1)
        except AuthenticationError:
            raise  # Don't retry auth errors
        except BadRequestError as e:
            print(f"Bad request: {e}")
            raise
        except APIStatusError as e:
            print(f"API error {e.status_code}: {e.message}")
            if e.status_code >= 500:
                time.sleep(2 ** attempt)
            else:
                raise
    raise RuntimeError("Max retries exceeded")

Built-in retry with tenacity

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type

@retry(
    retry=retry_if_exception_type(RateLimitError),
    wait=wait_exponential(multiplier=1, min=4, max=60),
    stop=stop_after_attempt(5),
)
def chat_with_retry(messages):
    return client.chat.completions.create(model="gpt-4o", messages=messages)

Error types

Error class Status Cause
AuthenticationError 401 Invalid API key
PermissionDeniedError 403 No access to model
NotFoundError 404 Model/resource not found
RateLimitError 429 TPM/RPM limit hit
BadRequestError 400 Invalid parameters, content policy
InternalServerError 500 OpenAI server error
APIConnectionError Network issue
APITimeoutError Request timed out

Token counting with tiktoken

import tiktoken

enc = tiktoken.encoding_for_model("gpt-4o")

text = "Hello, world! How are you?"
tokens = enc.encode(text)
print(len(tokens))  # 7

# Estimate cost before calling API
def count_messages_tokens(messages, model="gpt-4o"):
    enc = tiktoken.encoding_for_model(model)
    total = 0
    for msg in messages:
        total += 4  # message overhead
        total += len(enc.encode(msg["content"]))
    total += 2  # reply overhead
    return total

messages = [
    {"role": "system", "content": "You are helpful."},
    {"role": "user", "content": "Explain recursion in 2 sentences."},
]
print(count_messages_tokens(messages))

Models

Model Context Best for
gpt-4o 128k Default: best quality + speed balance
gpt-4o-mini 128k Cost-efficient for simple tasks
gpt-4-turbo 128k Legacy GPT-4 Turbo
gpt-4o-2024-08-06 128k Structured outputs support
o1 200k Complex reasoning (slower, no streaming)
o1-mini 128k Cost-efficient reasoning
o3-mini 200k Fastest reasoning model
text-embedding-3-small 8k Embeddings (cost-efficient)
text-embedding-3-large 8k Embeddings (highest accuracy)
dall-e-3 Image generation
whisper-1 Audio transcription
tts-1 / tts-1-hd Text-to-speech

Moderation

response = client.moderations.create(
    model="omni-moderation-latest",
    input="I want to hurt someone.",
)

result = response.results[0]
print(result.flagged)         # True
print(result.categories)     # Namespace of booleans per category
print(result.category_scores) # Namespace of floats 0–1

Categories: harassment, harassment/threatening, hate, hate/threatening, illicit, illicit/violent, self-harm, self-harm/instructions, self-harm/intent, sexual, sexual/minors, violence, violence/graphic

Practical patterns

System prompt best practices

messages = [
    {
        "role": "system",
        "content": """You are a senior Python developer.
Rules:
- Answer concisely, in 2–4 sentences max
- Always include a code example when relevant
- Use Python 3.12+ syntax
- If unsure, say so""",
    },
    {"role": "user", "content": "How do I read a file in Python?"},
]

Prompt template with variables

def build_prompt(language: str, task: str) -> str:
    return f"""Write a {language} function that {task}.
Requirements:
- Include type hints
- Handle errors
- Add a brief docstring"""

messages = [
    {"role": "system", "content": "You are an expert programmer."},
    {"role": "user", "content": build_prompt("Python", "validates an email address")},
]

Classify text

def classify(text: str, categories: list[str]) -> str:
    cats = ", ".join(categories)
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {
                "role": "system",
                "content": f"Classify the text into exactly one of: {cats}. Reply with only the category name.",
            },
            {"role": "user", "content": text},
        ],
        temperature=0,
    )
    return response.choices[0].message.content.strip()

print(classify("I love this product!", ["positive", "negative", "neutral"]))
# → "positive"

Extract structured data

from pydantic import BaseModel

class Invoice(BaseModel):
    vendor: str
    amount: float
    currency: str
    date: str
    line_items: list[str]

def extract_invoice(text: str) -> Invoice:
    response = client.beta.chat.completions.parse(
        model="gpt-4o-2024-08-06",
        messages=[
            {"role": "system", "content": "Extract invoice data from the text."},
            {"role": "user", "content": text},
        ],
        response_format=Invoice,
    )
    return response.choices[0].message.parsed

invoice_text = "Invoice from Acme Corp, $1,234.50 USD on 2024-03-15. Items: Widget x2, Gadget x1"
data = extract_invoice(invoice_text)
print(data.vendor, data.amount)

RAG (Retrieval-Augmented Generation) skeleton

def rag_answer(query: str, retrieved_chunks: list[str]) -> str:
    context = "\n\n".join(f"[{i+1}] {c}" for i, c in enumerate(retrieved_chunks))
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {
                "role": "system",
                "content": "Answer using only the provided context. If the answer is not in the context, say so.",
            },
            {
                "role": "user",
                "content": f"Context:\n{context}\n\nQuestion: {query}",
            },
        ],
    )
    return response.choices[0].message.content

Node.js / TypeScript

npm install openai
import OpenAI from "openai";

const client = new OpenAI(); // reads OPENAI_API_KEY

const response = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: "Hello!" },
  ],
});

console.log(response.choices[0].message.content);

Streaming in Node.js:

const stream = client.chat.completions.stream({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Tell me a story." }],
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
const finalResponse = await stream.finalChatCompletion();

Structured outputs in TypeScript:

import { zodResponseFormat } from "openai/helpers/zod";
import { z } from "zod";

const Step = z.object({
  explanation: z.string(),
  output: z.string(),
});

const MathSolution = z.object({
  steps: z.array(Step),
  final_answer: z.string(),
});

const completion = await client.beta.chat.completions.parse({
  model: "gpt-4o-2024-08-06",
  messages: [
    { role: "user", content: "Solve 8x + 31 = 2" },
  ],
  response_format: zodResponseFormat(MathSolution, "math_solution"),
});

const solution = completion.choices[0].message.parsed;
console.log(solution.final_answer);

Common mistakes

Mistake Fix
Hardcoding API key in source Use os.environ["OPENAI_API_KEY"] or .env
No retry on 429 Implement exponential backoff
Sending full history without pruning Trim oldest messages when approaching context limit
temperature=0 for creative tasks Use temperature=0.7–1.0 for creativity
Ignoring usage in response Track tokens to monitor cost
JSON mode without "JSON" in system prompt Always mention "JSON" in the prompt when using json_object
Structured outputs on wrong model Use gpt-4o-2024-08-06 or later for .parse()
Calling GPT-4 for every task Use gpt-4o-mini for classification/simple tasks

OpenAI API vs alternatives

Provider Best model Context Strengths
OpenAI gpt-4o 128k Best all-around, widest ecosystem
Anthropic claude-opus-4 200k Long docs, coding, safety
Google gemini-2.0-flash 1M Huge context, multimodal
Mistral mistral-large 128k European, open weights variants
Meta llama-3.3-70b 128k Open source, self-hostable
Groq llama-3.1-70b 128k Fastest inference (LPU)

FAQ

How do I get an API key?
Go to platform.openai.com, create an account, navigate to API Keys, and click "Create new secret key". Never commit this key to version control — use environment variables.

What's the difference between gpt-4o and gpt-4o-mini?
gpt-4o is the full model with the best quality (~15× more expensive). gpt-4o-mini is much cheaper and faster — use it for classification, summarisation, and simple tasks where top-tier quality isn't needed.

How do I avoid hitting rate limits?
Implement exponential backoff on RateLimitError, batch requests where possible, cache responses for identical prompts, and upgrade your usage tier on the OpenAI dashboard.

Why is my JSON output not valid JSON despite json_object mode?
The model must see the word "JSON" in the system or user prompt, otherwise the API returns an error. For guaranteed schema compliance, use beta.chat.completions.parse with a Pydantic model instead.

How do I reduce token costs?
Use gpt-4o-mini for simple tasks, cache embeddings (they're identical for identical text), trim conversation history to only necessary context, use max_tokens to cap output, and avoid redundant system prompts per request.

Can I use the API in a browser / frontend?
Technically yes, but never expose your API key in client-side code — it will be stolen. Always proxy through your own backend, which calls OpenAI with your secret key, then returns the result to the browser.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools