ChatGPT API Integration Guide
Introduction
OpenAI's ChatGPT API enables powerful AI capabilities in applications. This guide covers API setup, chat completions, GPT-4, function calling, embeddings, streaming responses, and building production-ready AI features.
1. API Setup
# Install OpenAI SDK
npm install openai
# Python
pip install openai
# Get API key from https://platform.openai.com/api-keys
# Node.js setup
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
# Python setup
from openai import OpenAI
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
# Test connection
async function testAPI() {
const completion = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: [
{ role: "user", content: "Hello!" }
]
});
console.log(completion.choices[0].message.content);
}
# Environment variables
# .env
OPENAI_API_KEY=sk-proj-...
OPENAI_ORG_ID=org-...
2. Chat Completions
// Basic chat completion
async function chat(userMessage) {
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: [
{
role: "system",
content: "You are a helpful assistant that specializes in programming."
},
{
role: "user",
content: userMessage
}
],
temperature: 0.7,
max_tokens: 500
});
return completion.choices[0].message.content;
}
// Conversation with history
class ChatBot {
constructor() {
this.messages = [
{
role: "system",
content: "You are a helpful customer support agent."
}
];
}
async sendMessage(userMessage) {
this.messages.push({
role: "user",
content: userMessage
});
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: this.messages
});
const assistantMessage = completion.choices[0].message;
this.messages.push(assistantMessage);
return assistantMessage.content;
}
clearHistory() {
this.messages = this.messages.slice(0, 1); // Keep system message
}
}
// Usage
const bot = new ChatBot();
const response1 = await bot.sendMessage("What's your return policy?");
const response2 = await bot.sendMessage("And what about refunds?");
// Parameters explained
{
model: "gpt-4", // Model version
temperature: 0.7, // Randomness (0-2, lower = focused)
max_tokens: 1000, // Max response length
top_p: 1, // Nucleus sampling
frequency_penalty: 0, // Penalize repetition (0-2)
presence_penalty: 0, // Encourage new topics (0-2)
stop: ["\n\n"], // Stop sequences
n: 1 // Number of completions
}
3. Streaming Responses
// Stream chat completion
async function streamChat(userMessage) {
const stream = await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: userMessage }],
stream: true
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
process.stdout.write(content);
}
}
// Express.js streaming endpoint
app.post('/api/chat/stream', async (req, res) => {
const { message } = req.body;
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const stream = await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: message }],
stream: true
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
if (content) {
res.write(`data: ${JSON.stringify({ content })}\n\n`);
}
}
res.write('data: [DONE]\n\n');
res.end();
});
// React component with streaming
function ChatComponent() {
const [messages, setMessages] = useState([]);
const [streaming, setStreaming] = useState(false);
const sendMessage = async (text) => {
setStreaming(true);
const newMessage = { role: 'assistant', content: '' };
setMessages(prev => [...prev, newMessage]);
const response = await fetch('/api/chat/stream', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: text })
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n').filter(line => line.trim());
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') continue;
const { content } = JSON.parse(data);
setMessages(prev => {
const updated = [...prev];
updated[updated.length - 1].content += content;
return updated;
});
}
}
}
setStreaming(false);
};
return ;
}
4. Function Calling
// Define functions
const functions = [
{
name: "get_weather",
description: "Get current weather for a location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "City name, e.g. San Francisco"
},
unit: {
type: "string",
enum: ["celsius", "fahrenheit"],
description: "Temperature unit"
}
},
required: ["location"]
}
},
{
name: "search_products",
description: "Search for products in database",
parameters: {
type: "object",
properties: {
query: {
type: "string",
description: "Search query"
},
category: {
type: "string",
description: "Product category"
},
max_price: {
type: "number",
description: "Maximum price"
}
},
required: ["query"]
}
}
];
// Function implementations
async function getWeather(location, unit = 'celsius') {
// Call weather API
const response = await fetch(`https://api.weather.com/v1/current?location=${location}`);
const data = await response.json();
return `Weather in ${location}: ${data.temp}°${unit === 'celsius' ? 'C' : 'F'}`;
}
async function searchProducts(query, category, maxPrice) {
// Query database
const products = await db.query(
'SELECT * FROM products WHERE name LIKE ? AND category = ? AND price <= ?',
[`%${query}%`, category, maxPrice]
);
return products;
}
// Chat with function calling
async function chatWithFunctions(userMessage) {
const messages = [{ role: "user", content: userMessage }];
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: messages,
functions: functions,
function_call: "auto"
});
const responseMessage = completion.choices[0].message;
// Check if function call
if (responseMessage.function_call) {
const functionName = responseMessage.function_call.name;
const functionArgs = JSON.parse(responseMessage.function_call.arguments);
let functionResponse;
switch (functionName) {
case "get_weather":
functionResponse = await getWeather(
functionArgs.location,
functionArgs.unit
);
break;
case "search_products":
functionResponse = await searchProducts(
functionArgs.query,
functionArgs.category,
functionArgs.max_price
);
break;
}
// Send function response back to model
messages.push(responseMessage);
messages.push({
role: "function",
name: functionName,
content: JSON.stringify(functionResponse)
});
const secondCompletion = await openai.chat.completions.create({
model: "gpt-4",
messages: messages
});
return secondCompletion.choices[0].message.content;
}
return responseMessage.content;
}
// Usage
const response = await chatWithFunctions("What's the weather in Paris?");
// GPT will call get_weather function and format the response
5. Embeddings for Semantic Search
// Generate embeddings
async function getEmbedding(text) {
const response = await openai.embeddings.create({
model: "text-embedding-ada-002",
input: text
});
return response.data[0].embedding;
}
// Cosine similarity
function cosineSimilarity(a, b) {
const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
return dotProduct / (magnitudeA * magnitudeB);
}
// Semantic search system
class SemanticSearch {
constructor() {
this.documents = [];
}
async addDocument(text, metadata = {}) {
const embedding = await getEmbedding(text);
this.documents.push({
text,
embedding,
metadata
});
}
async search(query, topK = 5) {
const queryEmbedding = await getEmbedding(query);
const results = this.documents.map(doc => ({
...doc,
similarity: cosineSimilarity(queryEmbedding, doc.embedding)
}));
return results
.sort((a, b) => b.similarity - a.similarity)
.slice(0, topK);
}
}
// Usage
const search = new SemanticSearch();
await search.addDocument("React is a JavaScript library for building UIs");
await search.addDocument("Vue.js is a progressive JavaScript framework");
await search.addDocument("Python is a high-level programming language");
const results = await search.search("JavaScript frameworks");
console.log(results);
// RAG (Retrieval Augmented Generation)
async function ragQuery(question, documents) {
// 1. Search relevant documents
const search = new SemanticSearch();
for (const doc of documents) {
await search.addDocument(doc);
}
const relevantDocs = await search.search(question, 3);
// 2. Create context
const context = relevantDocs
.map(doc => doc.text)
.join('\n\n');
// 3. Query GPT with context
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: [
{
role: "system",
content: "Answer based on the provided context. If the answer isn't in the context, say so."
},
{
role: "user",
content: `Context:\n${context}\n\nQuestion: ${question}`
}
]
});
return completion.choices[0].message.content;
}
6. Image Generation with DALL-E
// Generate image
async function generateImage(prompt) {
const response = await openai.images.generate({
model: "dall-e-3",
prompt: prompt,
n: 1,
size: "1024x1024",
quality: "standard", // or "hd"
style: "vivid" // or "natural"
});
return response.data[0].url;
}
// Usage
const imageUrl = await generateImage(
"A futuristic city with flying cars, cyberpunk style"
);
// Image variations
async function createVariation(imageFile) {
const response = await openai.images.createVariation({
image: fs.createReadStream(imageFile),
n: 2,
size: "1024x1024"
});
return response.data.map(img => img.url);
}
// Edit image
async function editImage(imageFile, maskFile, prompt) {
const response = await openai.images.edit({
image: fs.createReadStream(imageFile),
mask: fs.createReadStream(maskFile),
prompt: prompt,
n: 1,
size: "1024x1024"
});
return response.data[0].url;
}
7. Production Best Practices
// Rate limiting
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use('/api/chat', limiter);
// Error handling
async function safeCompletion(messages) {
try {
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: messages
});
return {
success: true,
content: completion.choices[0].message.content
};
} catch (error) {
if (error.response) {
// API error
console.error('OpenAI API error:', error.response.status);
return {
success: false,
error: `API error: ${error.response.status}`
};
} else if (error.code === 'ECONNABORTED') {
// Timeout
return {
success: false,
error: 'Request timeout'
};
} else {
// Other errors
console.error('Unexpected error:', error);
return {
success: false,
error: 'Unexpected error occurred'
};
}
}
}
// Token counting and management
import { encode } from 'gpt-3-encoder';
function countTokens(text) {
return encode(text).length;
}
function truncateToTokenLimit(text, maxTokens) {
const tokens = encode(text);
if (tokens.length <= maxTokens) return text;
const truncated = tokens.slice(0, maxTokens);
return decode(truncated);
}
// Cost tracking
class CostTracker {
constructor() {
this.costs = {
'gpt-4': { input: 0.03, output: 0.06 }, // per 1K tokens
'gpt-3.5-turbo': { input: 0.0015, output: 0.002 }
};
}
calculateCost(model, inputTokens, outputTokens) {
const rates = this.costs[model];
const inputCost = (inputTokens / 1000) * rates.input;
const outputCost = (outputTokens / 1000) * rates.output;
return inputCost + outputCost;
}
async trackCompletion(completion) {
const usage = completion.usage;
const cost = this.calculateCost(
completion.model,
usage.prompt_tokens,
usage.completion_tokens
);
await db.query(
'INSERT INTO api_usage (model, tokens, cost, timestamp) VALUES (?, ?, ?, ?)',
[completion.model, usage.total_tokens, cost, new Date()]
);
return cost;
}
}
// Caching responses
const cache = new Map();
async function cachedCompletion(messages, ttl = 3600) {
const cacheKey = JSON.stringify(messages);
if (cache.has(cacheKey)) {
const cached = cache.get(cacheKey);
if (Date.now() - cached.timestamp < ttl * 1000) {
return cached.response;
}
}
const response = await openai.chat.completions.create({
model: "gpt-4",
messages: messages
});
cache.set(cacheKey, {
response: response.choices[0].message.content,
timestamp: Date.now()
});
return response.choices[0].message.content;
}
// Content moderation
async function moderateContent(text) {
const response = await openai.moderations.create({
input: text
});
const result = response.results[0];
return {
flagged: result.flagged,
categories: result.categories,
scores: result.category_scores
};
}
// Usage
const moderation = await moderateContent(userInput);
if (moderation.flagged) {
return { error: 'Content violates policy' };
}
8. Best Practices
✓ ChatGPT API Best Practices:
- ✓ Always use environment variables for API keys
- ✓ Implement rate limiting to prevent abuse
- ✓ Handle errors gracefully with retry logic
- ✓ Monitor token usage and costs
- ✓ Use appropriate models (GPT-3.5 for simple, GPT-4 for complex)
- ✓ Implement content moderation for user inputs
- ✓ Cache responses when appropriate
- ✓ Stream responses for better UX
- ✓ Keep conversation history manageable
- ✓ Use system messages to set behavior
- ✓ Sanitize and validate user inputs
- ✓ Set reasonable timeouts
- ✓ Log API usage for debugging
- ✓ Test thoroughly before production
- ✓ Follow OpenAI usage policies
Conclusion
ChatGPT API enables powerful AI features in applications. Master chat completions, streaming, function calling, and embeddings for semantic search. Always implement proper error handling, rate limiting, and cost tracking for production deployments. Use RAG for knowledge-based applications.
💡 Pro Tip: Combine embeddings with vector databases like Pinecone or Weaviate for production-scale semantic search. This enables efficient similarity search over millions of documents with sub-second latency. Perfect for building chatbots with large knowledge bases, recommendation systems, and intelligent search features.