ChatGPT API Complete Guide: Build AI Apps in Any Language
The ChatGPT API is the most powerful and accessible AI API available. This complete guide shows you how to integrate it into your projects.
ChatGPT API Complete Guide: Build AI Apps in Any Language (2026)
The OpenAI API is the most widely integrated AI capability in the world. It powers everything from startup MVPs to enterprise applications serving millions of users. Understanding it deeply — not just how to make basic calls, but how to architect real applications — is one of the most valuable technical skills you can acquire in 2026.
This comprehensive guide covers everything from your first API call to advanced patterns like streaming, function calling, structured outputs, and cost optimization strategies.
Understanding the OpenAI API
What It Is (and Isn't)
The OpenAI API is an HTTP API that gives programmatic access to OpenAI's language models. When people say "the ChatGPT API," they typically mean the /chat/completions endpoint — the same underlying model powering ChatGPT, accessible via code.
Unlike the ChatGPT web interface, the API gives you:
- Programmatic control over every parameter
- The ability to embed AI in your own applications
- No conversation history persistence — you manage context
- Full control over system instructions
- Pay-per-token pricing (no subscription cap)
- Access to multiple models for different use cases
Available Models in 2026
GPT-4o — The flagship model. Best reasoning, writing quality, and instruction following. Use for complex tasks where quality matters most.
GPT-4o mini — 10–15x cheaper than GPT-4o, with surprisingly strong performance on most tasks. Use as your default and upgrade to GPT-4o only when needed.
GPT-4o with vision — Accepts images as input alongside text. Analyze photos, diagrams, screenshots, and documents.
o1 / o3 — OpenAI's reasoning models optimized for complex problem-solving, math, and coding. Much slower and more expensive, but dramatically better on hard reasoning tasks.
text-embedding-3-large / small — Not for chat; these convert text to numerical vectors for semantic search and similarity matching.
Whisper — Speech-to-text transcription, supporting 100+ languages.
TTS (Text-to-Speech) — Convert text to natural-sounding audio in multiple voices.
DALL·E 3 — Image generation from text descriptions.
Getting Started
Installation
# Python
pip install openai
# Node.js
npm install openai
Authentication
from openai import OpenAI
# Option 1: Pass API key directly (not recommended for production)
client = OpenAI(api_key="sk-your-key-here")
# Option 2: Set environment variable (recommended)
import os
os.environ["OPENAI_API_KEY"] = "sk-your-key-here"
client = OpenAI() # Automatically reads from environment
Get your API key at platform.openai.com/api-keys.
Your First API Call
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": "You are a helpful, concise AI assistant."
},
{
"role": "user",
"content": "What is quantum entanglement? Explain it simply."
}
]
)
# Extract the response text
print(response.choices[0].message.content)
# Check token usage
print(f"Tokens used: {response.usage.total_tokens}")
print(f"Approximate cost: ${response.usage.total_tokens * 0.000005:.6f}")
Understanding the Messages Format
The messages array is the heart of the Chat Completions API. It represents a conversation with three role types:
messages = [
# System: Sets the AI's behavior and persona
{
"role": "system",
"content": "You are an expert data scientist with 15 years of experience. Provide precise, technical answers. When showing code, always include comments."
},
# User: The human's messages
{
"role": "user",
"content": "How do I handle missing values in a pandas DataFrame?"
},
# Assistant: Previous AI responses (for multi-turn conversations)
{
"role": "assistant",
"content": "There are several approaches depending on your situation..."
},
# Continue the conversation
{
"role": "user",
"content": "What if the missing values are in a time series column?"
}
]
Building a conversational application means maintaining this messages array, appending each exchange as the conversation progresses.
Key Parameters Explained
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
# Temperature: 0 = deterministic, 2 = very random
# Use 0 for factual/code tasks; 0.7-1 for creative tasks
temperature=0.7,
# Maximum response length in tokens (~0.75 words per token)
max_tokens=1000,
# Alternative to temperature; use one or the other
# top_p=0.9,
# Number of responses to generate (each costs tokens)
n=1,
# Sequences that cause the model to stop generating
stop=["END", "---"],
# Penalizes repetition of recent tokens (0-2 scale)
presence_penalty=0.1,
# Penalizes frequently appearing tokens (0-2 scale)
frequency_penalty=0.1,
)
Streaming Responses
Streaming returns tokens as they're generated — providing a dramatically better user experience for long responses:
from openai import OpenAI
client = OpenAI()
# Create a streaming request
stream = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": "Write a comprehensive guide to machine learning"}
],
stream=True,
)
# Print tokens as they arrive
for chunk in stream:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="", flush=True)
print() # New line at end
Streaming in a Web Application (FastAPI)
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from openai import OpenAI
app = FastAPI()
client = OpenAI()
@app.post("/chat")
async def chat_stream(user_message: str):
def generate():
stream = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": user_message}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
yield chunk.choices[0].delta.content
return StreamingResponse(generate(), media_type="text/plain")
Function Calling (Tool Use)
Function calling allows the AI to request that your code run a specific function, then incorporate the result. This bridges AI reasoning with real-world actions:
import json
from openai import OpenAI
client = OpenAI()
# Define the functions available to the AI
tools = [
{
"type": "function",
"function": {
"name": "search_products",
"description": "Search the product catalog by keyword and filters",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query"
},
"category": {
"type": "string",
"enum": ["electronics", "clothing", "books", "home"],
"description": "Product category to filter by"
},
"max_price": {
"type": "number",
"description": "Maximum price in USD"
}
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Get the status of a customer order by order ID",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "The order ID to look up"
}
},
"required": ["order_id"]
}
}
}
]
# Simulated function implementations
def search_products(query: str, category: str = None, max_price: float = None):
# In production, this queries your actual database
return [
{"id": "P001", "name": "Wireless Headphones", "price": 89.99, "rating": 4.7},
{"id": "P002", "name": "Bluetooth Speaker", "price": 49.99, "rating": 4.5},
]
def get_order_status(order_id: str):
return {"order_id": order_id, "status": "shipped", "eta": "2026-07-08"}
def run_function(name: str, arguments: dict):
if name == "search_products":
return search_products(**arguments)
elif name == "get_order_status":
return get_order_status(**arguments)
# Agentic loop
def process_with_tools(user_message: str):
messages = [{"role": "user", "content": user_message}]
while True:
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto"
)
message = response.choices[0].message
# If no tool calls, we have the final response
if not message.tool_calls:
return message.content
# Process tool calls
messages.append(message)
for tool_call in message.tool_calls:
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
# Run the actual function
result = run_function(function_name, arguments)
# Add result to messages
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result)
})
# Test it
print(process_with_tools("I'm looking for wireless headphones under $100"))
print(process_with_tools("What's the status of order ORD-2026-4821?"))
Structured Output (JSON Mode)
For applications that need to parse AI responses, structured output guarantees valid JSON:
from pydantic import BaseModel
from typing import List, Optional
class ProductReview(BaseModel):
sentiment: str # "positive", "negative", "neutral"
score: int # 1-10
key_positives: List[str]
key_negatives: List[str]
summary: str
recommend: bool
# Using Pydantic model for structured output
response = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[
{
"role": "system",
"content": "Analyze the product review and extract structured information."
},
{
"role": "user",
"content": """Review: "Great headphones overall. The sound quality is
excellent and battery life lasts all day. The noise canceling could be
better and they're a bit heavy after a few hours. Would recommend for
the price point." """
}
],
response_format=ProductReview,
)
review = response.choices[0].message.parsed
print(f"Sentiment: {review.sentiment}")
print(f"Score: {review.score}/10")
print(f"Would Recommend: {review.recommend}")
print(f"Positives: {', '.join(review.key_positives)}")
Vision: Analyzing Images
import base64
from pathlib import Path
def encode_image(image_path: str) -> str:
with open(image_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
# Analyze a local image
image_b64 = encode_image("product_image.jpg")
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{image_b64}",
"detail": "high" # "low" for faster/cheaper analysis
}
},
{
"type": "text",
"text": "Describe this product in detail for an e-commerce listing. Include dimensions if visible, colors, materials, and any unique features."
}
]
}
]
)
print(response.choices[0].message.content)
Cost Optimization Strategies
Choose the Right Model
- GPT-4o mini: Use for 80% of tasks — routing, classification, simple Q&A, text extraction
- GPT-4o: Reserve for complex reasoning, nuanced writing, difficult coding tasks
- o1/o3: Only for genuinely hard math, science, or multi-step reasoning problems
Implement Prompt Caching
Identical prefix portions of prompts (system messages, few-shot examples) are cached automatically, reducing costs by 50% for cache hits.
Use the Batch API
For non-real-time processing, the Batch API gives a 50% discount by processing requests within 24 hours:
# Submit batch job
batch = client.batches.create(
input_file_id=file_id, # JSONL file with many requests
endpoint="/v1/chat/completions",
completion_window="24h"
)
Monitor and Set Limits
- Set spending limits in the OpenAI dashboard
- Monitor token usage per request to identify prompt bloat
- Log costs per user/feature to understand true AI economics
Tiered Processing
Route requests based on complexity:
def smart_route(user_message: str, complexity: str = "auto"):
if complexity == "simple" or len(user_message) < 200:
model = "gpt-4o-mini"
else:
model = "gpt-4o"
return client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": user_message}]
)
Building a Production-Ready AI API
Here's a complete FastAPI application incorporating best practices:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from openai import OpenAI
import time
import logging
app = FastAPI()
client = OpenAI()
logger = logging.getLogger(__name__)
class ChatRequest(BaseModel):
message: str
conversation_history: list = []
model: str = "gpt-4o-mini"
@app.post("/chat")
async def chat(request: ChatRequest):
try:
messages = [
{"role": "system", "content": "You are a helpful AI assistant."},
*request.conversation_history,
{"role": "user", "content": request.message}
]
start_time = time.time()
response = client.chat.completions.create(
model=request.model,
messages=messages,
max_tokens=1000,
temperature=0.7,
)
latency = time.time() - start_time
return {
"response": response.choices[0].message.content,
"tokens_used": response.usage.total_tokens,
"model": request.model,
"latency_seconds": round(latency, 3)
}
except Exception as e:
logger.error(f"OpenAI API error: {e}")
raise HTTPException(status_code=500, detail=str(e))
Rate Limits and Error Handling
import time
from openai import RateLimitError, APIError
def robust_api_call(messages, max_retries=3):
for attempt in range(max_retries):
try:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages
)
return response.choices[0].message.content
except RateLimitError:
wait_time = 2 ** attempt # Exponential backoff
logger.warning(f"Rate limit hit, waiting {wait_time}s")
time.sleep(wait_time)
except APIError as e:
logger.error(f"API error: {e}")
if attempt == max_retries - 1:
raise
raise Exception("Max retries exceeded")
Ready to build more? LearnGeni's ChatGPT API guide goes deeper into Assistants API, file handling, fine-tuning GPT-4o on custom data, production deployment patterns, and cost optimization at scale — available in your language as part of the 30-guide AI Mastery Program.
Earn Your International AI Certificate
This article is part of the LearnGeni AI Mastery Program — 30 comprehensive guides in 50+ languages. Complete all 30 and earn a certificate backed by WhatsGeni (Official Meta AI Partner), recognized in 50+ countries.