AI Engineering — OpenAI API
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.
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.
| 1 | // Installation |
| 2 | // npm install openai |
| 3 | |
| 4 | // TypeScript SDK setup |
| 5 | import OpenAI from "openai"; |
| 6 | |
| 7 | const 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 | }); |
| 1 | # Python SDK setup |
| 2 | # pip install openai |
| 3 | |
| 4 | from openai import OpenAI |
| 5 | |
| 6 | client = OpenAI( |
| 7 | api_key=os.environ["OPENAI_API_KEY"], |
| 8 | timeout=30.0, |
| 9 | max_retries=3 |
| 10 | ) |
warning
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.
| 1 | // Basic chat completion |
| 2 | const 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 | |
| 22 | console.log(response.choices[0].message.content); |
| 23 | |
| 24 | // Response metadata |
| 25 | console.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.
| Parameter | Range | Effect |
|---|---|---|
| temperature | 0 - 2 | Randomness in output. Lower = more deterministic. |
| top_p | 0 - 1 | Nucleus sampling. Consider tokens with top_p probability mass. |
| max_tokens | 1 - 16384 | Maximum tokens in the response (not including prompt). |
| frequency_penalty | -2 - 2 | Penalize token repetition. Positive values reduce repetition. |
| presence_penalty | -2 - 2 | Penalize tokens that have appeared. Encourages topic diversity. |
Streaming delivers tokens incrementally as they are generated, reducing perceived latency. The API uses Server-Sent Events (SSE) for streaming responses.
| 1 | // Streaming chat completion |
| 2 | const 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 | |
| 10 | let fullResponse = ""; |
| 11 | |
| 12 | for await (const chunk of stream) { |
| 13 | const content = chunk.choices[0]?.delta?.content || ""; |
| 14 | fullResponse += content; |
| 15 | process.stdout.write(content); |
| 16 | } |
| 17 | |
| 18 | console.log("\n--- Full response ---"); |
| 19 | console.log(fullResponse); |
| 1 | # Python streaming example |
| 2 | stream = 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 | |
| 10 | full_response = "" |
| 11 | for 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
The embeddings endpoint converts text into vector representations (embeddings). These capture semantic meaning and enable similarity search, clustering, classification, and RAG (Retrieval-Augmented Generation).
| 1 | // Generate embeddings |
| 2 | const 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 | |
| 8 | console.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 |
| 14 | function 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 | |
| 21 | const text1 = await openai.embeddings.create({ |
| 22 | model: "text-embedding-3-small", |
| 23 | input: "Machine learning is fascinating" |
| 24 | }); |
| 25 | |
| 26 | const text2 = await openai.embeddings.create({ |
| 27 | model: "text-embedding-3-small", |
| 28 | input: "Deep neural networks are powerful" |
| 29 | }); |
| 30 | |
| 31 | const similarity = cosineSimilarity( |
| 32 | text1.data[0].embedding, |
| 33 | text2.data[0].embedding |
| 34 | ); |
| 35 | console.log({ similarity }); // Closer to 1 = more similar |
| Model | Dimensions | Max Input | Pricing (per 1M tokens) |
|---|---|---|---|
| text-embedding-3-small | 512 (default), can be reduced | 8191 tokens | $0.02 |
| text-embedding-3-large | 3072 (default) | 8191 tokens | $0.13 |
| text-embedding-ada-002 | 1536 | 8191 tokens | $0.10 (legacy) |
info
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.
| 1 | // Robust error handling |
| 2 | import OpenAI from "openai"; |
| 3 | import { RateLimitError, APIError } from "openai/error"; |
| 4 | |
| 5 | async 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 |
| 33 | async 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
| Model | Input (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/image | per image |
| Whisper | $0.006/minute | per audio minute |
| TTS | $15.00/1M chars | per character |
best practice