|$ curl https://forge-ai.dev/api/markdown?path=docs/ai/openai
$cat docs/ai-engineering-—-openai-api.md
updated Recently·45 min read·published

AI Engineering — OpenAI API

AI EngineeringAPIsBeginner to Advanced
Introduction

OpenAI provides a comprehensive API for accessing GPT models (GPT-4o, GPT-4o-mini, o-series), embedding models, image generation (DALL-E 3), audio transcription (Whisper), text-to-speech (TTS), and the Assistants API for stateful agent development.

The OpenAI API uses a RESTful interface with JSON request/response bodies. All requests require authentication via an API key sent in the Authorization header. The API is available globally with region-specific endpoints for latency optimization.

Authentication & Setup

API keys are managed in the OpenAI dashboard. Use environment variables to store keys — never hardcode them. The official SDKs handle authentication automatically when you provide the API key.

setup.ts
TypeScript
1// Installation
2// npm install openai
3
4// TypeScript SDK setup
5import OpenAI from "openai";
6
7const openai = new OpenAI({
8 apiKey: process.env.OPENAI_API_KEY,
9 // Optional: custom base URL for Azure or proxies
10 // baseURL: "https://api.openai.com/v1",
11 // Optional: timeout
12 timeout: 30000,
13 maxRetries: 3,
14});
setup.py
Python
1# Python SDK setup
2# pip install openai
3
4from openai import OpenAI
5
6client = OpenAI(
7 api_key=os.environ["OPENAI_API_KEY"],
8 timeout=30.0,
9 max_retries=3
10)

warning

Never expose API keys in client-side code. Use server-side routes or API route handlers (Next.js API routes, Express middleware) to proxy requests. Keys in client bundles can be extracted and abused, leading to unexpected charges.
Chat Completions

The chat completions endpoint is the primary interface for interacting with OpenAI's language models. It accepts a list of messages with roles (system, user, assistant, tool) and returns a model-generated message.

chat-completion.ts
TypeScript
1// Basic chat completion
2const response = await openai.chat.completions.create({
3 model: "gpt-4o",
4 messages: [
5 {
6 role: "system",
7 content: "You are a helpful assistant. " +
8 "Be concise and accurate."
9 },
10 {
11 role: "user",
12 content: "What is the capital of France?"
13 }
14 ],
15 temperature: 0.7,
16 max_tokens: 500,
17 top_p: 1,
18 frequency_penalty: 0,
19 presence_penalty: 0
20});
21
22console.log(response.choices[0].message.content);
23
24// Response metadata
25console.log({
26 id: response.id,
27 model: response.model,
28 usage: {
29 prompt_tokens: response.usage?.prompt_tokens,
30 completion_tokens: response.usage?.completion_tokens,
31 total_tokens: response.usage?.total_tokens
32 }
33});

The temperature parameter controls randomness (0-2, default 1). Lower values produce more deterministic, focused outputs. Higher values produce more creative, varied outputs. Use low temperature (0-0.3) for factual tasks, higher for creative tasks.

ParameterRangeEffect
temperature0 - 2Randomness in output. Lower = more deterministic.
top_p0 - 1Nucleus sampling. Consider tokens with top_p probability mass.
max_tokens1 - 16384Maximum tokens in the response (not including prompt).
frequency_penalty-2 - 2Penalize token repetition. Positive values reduce repetition.
presence_penalty-2 - 2Penalize tokens that have appeared. Encourages topic diversity.
Streaming

Streaming delivers tokens incrementally as they are generated, reducing perceived latency. The API uses Server-Sent Events (SSE) for streaming responses.

streaming.ts
TypeScript
1// Streaming chat completion
2const stream = await openai.chat.completions.create({
3 model: "gpt-4o",
4 messages: [
5 { role: "user", content: "Write a short poem about AI." }
6 ],
7 stream: true
8});
9
10let fullResponse = "";
11
12for await (const chunk of stream) {
13 const content = chunk.choices[0]?.delta?.content || "";
14 fullResponse += content;
15 process.stdout.write(content);
16}
17
18console.log("\n--- Full response ---");
19console.log(fullResponse);
streaming.py
Python
1# Python streaming example
2stream = client.chat.completions.create(
3 model="gpt-4o",
4 messages=[
5 {"role": "user", "content": "Write a poem about AI."}
6 ],
7 stream=True
8)
9
10full_response = ""
11for chunk in stream:
12 if chunk.choices[0].delta.content is not None:
13 content = chunk.choices[0].delta.content
14 full_response += content
15 print(content, end="", flush=True)
🔥

pro tip

In streaming mode, response metadata (usage, finish_reason) arrives in the final chunk. Accumulate chunks to reconstruct the full message. Use libraries like Vercel AI SDK for framework-native streaming support in React/Next.js.
Embeddings

The embeddings endpoint converts text into vector representations (embeddings). These capture semantic meaning and enable similarity search, clustering, classification, and RAG (Retrieval-Augmented Generation).

embeddings.ts
TypeScript
1// Generate embeddings
2const embedding = await openai.embeddings.create({
3 model: "text-embedding-3-small",
4 input: "The quick brown fox jumps over the lazy dog",
5 encoding_format: "float" // or "base64"
6});
7
8console.log({
9 dimensions: embedding.data[0].embedding.length, // 512 for small, 1536 for large, 3072 for 3-large
10 vector: embedding.data[0].embedding.slice(0, 5), // First 5 values
11});
12
13// Compare two texts with cosine similarity
14function cosineSimilarity(a: number[], b: number[]): number {
15 const dot = a.reduce((sum, val, i) => sum + val * b[i], 0);
16 const magA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
17 const magB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
18 return dot / (magA * magB);
19}
20
21const text1 = await openai.embeddings.create({
22 model: "text-embedding-3-small",
23 input: "Machine learning is fascinating"
24});
25
26const text2 = await openai.embeddings.create({
27 model: "text-embedding-3-small",
28 input: "Deep neural networks are powerful"
29});
30
31const similarity = cosineSimilarity(
32 text1.data[0].embedding,
33 text2.data[0].embedding
34);
35console.log({ similarity }); // Closer to 1 = more similar
ModelDimensionsMax InputPricing (per 1M tokens)
text-embedding-3-small512 (default), can be reduced8191 tokens$0.02
text-embedding-3-large3072 (default)8191 tokens$0.13
text-embedding-ada-00215368191 tokens$0.10 (legacy)

info

Use text-embedding-3-small for most use cases — it offers the best cost-quality trade-off. You can reduce dimensions (e.g., dimensions: 256) for faster search at minimal quality loss. Always normalize embeddings for cosine similarity.
Error Handling & Rate Limits

The OpenAI API returns standard HTTP status codes. Rate limits (429) and server errors (500) should be handled with exponential backoff retry logic. The SDK provides built-in retry handling with configurable maxRetries.

error-handling.ts
TypeScript
1// Robust error handling
2import OpenAI from "openai";
3import { RateLimitError, APIError } from "openai/error";
4
5async function safeCompletion(params: any) {
6 try {
7 return await openai.chat.completions.create(params);
8 } catch (error) {
9 if (error instanceof RateLimitError) {
10 console.warn("Rate limited, backing off...");
11 const retryAfter = error.headers?.["retry-after-ms"]
12 ? parseInt(error.headers["retry-after-ms"])
13 : 5000;
14 await new Promise(r => setTimeout(r, retryAfter));
15 return safeCompletion(params); // Retry
16 }
17
18 if (error instanceof APIError) {
19 console.error(`API Error ${error.status}: ${error.message}`);
20 if (error.status === 401) {
21 throw new Error("Invalid API key. Check your OPENAI_API_KEY.");
22 }
23 if (error.status === 400) {
24 throw new Error(`Bad request: ${error.message}`);
25 }
26 }
27
28 throw error;
29 }
30}
31
32// Custom retry with exponential backoff
33async function withRetry(
34 fn: () => Promise<any>,
35 maxRetries = 5,
36 baseDelay = 1000
37) {
38 for (let i = 0; i < maxRetries; i++) {
39 try {
40 return await fn();
41 } catch (err) {
42 if (i === maxRetries - 1) throw err;
43 const delay = baseDelay * Math.pow(2, i) + Math.random() * 1000;
44 console.log(`Retry ${i + 1}/${maxRetries} after ${delay}ms`);
45 await new Promise(r => setTimeout(r, delay));
46 }
47 }
48}

warning

Rate limits vary by tier (Free, Tier 1-5). Check your account's rate limits in the OpenAI dashboard and implement client-side rate limiting to avoid 429 errors. Use tokens-per-minute (TPM) and requests-per-minute (RPM) limits as hard caps in your application.
Model Pricing (Per Million Tokens)
ModelInput (per 1M)Output (per 1M)
GPT-4o$2.50$10.00
GPT-4o-mini$0.15$0.60
o1 / o3$15.00$60.00
o1-mini$3.00$12.00
GPT-4o-audio-preview$2.50 + audio$10.00 + audio
DALL-E 3$0.04-0.08/imageper image
Whisper$0.006/minuteper audio minute
TTS$15.00/1M charsper character

best practice

Use GPT-4o-mini for simple tasks (classification, extraction, summarization) and reserve GPT-4o for complex reasoning, code generation, and agent orchestration. Monitor token usage via the usage field in responses and set budget alerts in the OpenAI dashboard.
$Blueprint — Engineering Documentation·Section ID: AI-OAI-01·Revision: 1.0