Back to Articles
AI EngineeringJavaScriptTutorialOpenAI

Your First AI API Call: A Complete Guide for JavaScript Developers

Frank Atukunda
Frank Atukunda
Software Engineer
December 6, 2025
8 min read
Your First AI API Call: A Complete Guide for JavaScript Developers

This is the post where you stop reading and start building.

By the end of this guide, you'll have made your first AI API call, seen the response, and understood exactly what's happening under the hood. No theory, no fluff—just working code.

What You'll Build

By the end of this tutorial, you'll have a working script that can:

  • Query an AI model and get responses
  • Stream responses in real-time (like ChatGPT)
  • Handle errors gracefully

Total time: ~15 minutes. Total cost: less than $0.01.

Prerequisites

Before we start, make sure you have:

  • Node.js 18+ installed (required for native fetch support)
  • npm (comes with Node.js)
  • A text editor (VS Code, Cursor, etc.)

That's it. Let's go.

Step 1: Get Your API Key

We'll use OpenAI since it's the most common starting point.

  1. Go to platform.openai.com
  2. Create an account or log in
  3. Add a payment method — Even if you have free credits, the API requires a card on file. Without it, your calls will silently fail.
  4. Click your profile icon → API Keys
  5. Click Create new secret key
  6. Give it a name (e.g., "my-first-app")
  7. Copy the key immediately — you won't see it again

Your key looks something like: sk-proj-abc123...

Store it somewhere safe. We'll use it in a moment.

Security note: If you ever accidentally expose your API key (e.g., push it to GitHub), regenerate it immediately from the API Keys page. Exposed keys can be used by anyone and you'll be billed for their usage.

Worried about costs? The examples in this tutorial cost roughly $0.001 total. You'd need to run them thousands of times to spend even $1. We debunked the cost myth in detail → 5 AI Myths.

Step 2: Set Up Your Project

Open your terminal and run:

mkdir my-first-ai-app
cd my-first-ai-app
npm init -y
npm install openai dotenv
npm install -D typescript tsx @types/node

Create three files:

touch index.ts .env .gitignore

Add your API key to .env:

OPENAI_API_KEY=sk-proj-your-key-here

Add this to .gitignore (never commit your API key):

.env
node_modules

That's your project set up. A few commands, three files.

Step 3: Your First API Call

Open index.ts and paste this code:

import OpenAI from 'openai'
import 'dotenv/config' // This line loads your .env file into process.env
 
const openai = new OpenAI() // Automatically reads OPENAI_API_KEY from environment
 
async function main() {
  const response = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user', content: 'What is the capital of France?' }
    ]
  })
 
  console.log(response.choices[0].message.content)
}
 
main()

Run it:

npx tsx index.ts

Expected output:

The capital of France is Paris.

🎉 You just made your first AI API call.

Let me break down what happened:

  • import 'dotenv/config' — Loads your .env file so OPENAI_API_KEY is available. Don't remove this line!
  • new OpenAI() — Creates the client, automatically reading your API key from the environment
  • model: 'gpt-4o-mini' — A fast, cheap model perfect for learning (~$0.15 per million input tokens)
  • messages — The conversation: a system prompt (sets behavior) and a user message (your question)
  • response.choices[0].message.content — The model's actual answer

Note on models: OpenAI frequently updates their model lineup. Check OpenAI's pricing page for current options. If gpt-4o-mini isn't available, gpt-3.5-turbo is an even cheaper alternative.

Step 4: Understanding the Response

The response object contains more than just the answer. Let's see the full structure:

console.log(JSON.stringify(response, null, 2))

You'll see something like:

{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "model": "gpt-4o-mini-2024-07-18",
  "usage": {
    "prompt_tokens": 25,
    "completion_tokens": 8,
    "total_tokens": 33
  },
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "The capital of France is Paris."
      },
      "finish_reason": "stop"
    }
  ]
}

Key fields to know:

  • usage.prompt_tokens — How many tokens your input used
  • usage.completion_tokens — How many tokens the response used
  • usage.total_tokens — What you're billed for (33 tokens ≈ $0.000005)
  • finish_reason: "stop" — The model finished naturally (vs. being cut off by max_tokens)

Want to understand tokens better? We covered them in detail → LLM Glossary.

Step 5: Streaming Responses

For chat-like experiences, you don't want to wait for the entire response. You want it to appear word-by-word, like ChatGPT.

When to use streaming:

  • User-facing chat interfaces where perceived speed matters
  • Long responses where you want to show progress
  • Any UI where waiting feels slow

When to use standard calls:

  • Background processing where you need the full response before continuing
  • Short responses where streaming overhead isn't worth it
  • When you need accurate token counts (streaming doesn't return usage stats)

Here's how to stream:

import OpenAI from 'openai'
import 'dotenv/config'
 
const openai = new OpenAI()
 
async function main() {
  const stream = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [
      { role: 'user', content: 'Write a haiku about coding.' }
    ],
    stream: true
  })
 
  for await (const chunk of stream) {
    const content = chunk.choices[0]?.delta?.content || ''
    process.stdout.write(content)
  }
  
  console.log() // New line at the end
}
 
main()

What's different:

  • stream: true — Tells the API to send chunks as they're generated
  • delta.content — Each chunk contains a small piece of text
  • process.stdout.write() — Prints without newlines, so it flows naturally

Watch the haiku appear character by character. This is how you build responsive AI UIs.

Step 6: Handling Errors

Things will go wrong. Here's what to expect and how to fix it:

Common Errors

Invalid API Key:

Error: 401 Incorrect API key provided

→ Check your .env file. Make sure there are no extra spaces. Regenerate your key if needed.

No Payment Method:

Error: 429 You exceeded your current quota

→ Even with free credits, you need a payment method on file. Add one at platform.openai.com/account/billing.

Rate Limited:

Error: 429 Rate limit reached

→ You're making too many requests. Wait a minute and try again. For production apps, implement exponential backoff.

Model Not Found:

Error: 404 The model does not exist

→ Typo in the model name. It's gpt-4o-mini, not gpt4-mini or gpt-4-o-mini.

Error Handling Pattern

Always wrap your API calls:

import OpenAI from 'openai'
import 'dotenv/config'
 
const openai = new OpenAI()
 
async function main() {
  try {
    const response = await openai.chat.completions.create({
      model: 'gpt-4o-mini',
      messages: [
        { role: 'user', content: 'Hello!' }
      ]
    })
    console.log(response.choices[0].message.content)
  } catch (error) {
    if (error instanceof OpenAI.APIError) {
      console.error(`API Error: ${error.status} - ${error.message}`)
      
      // Handle specific errors
      if (error.status === 401) {
        console.error('Check your API key in .env')
      } else if (error.status === 429) {
        console.error('Rate limited. Wait and retry.')
      }
    } else {
      throw error
    }
  }
}
 
main()

What's Next?

You've made your first API call. You understand the response. You can stream. You can handle errors.

Now what?

  1. Experiment with prompts — Change the system message, ask different questions, see how behavior changes
  2. Build something real — A CLI chatbot, a document summarizer, a code explainer
  3. Try other models — GPT-4o for complex reasoning, or explore Claude (Anthropic) and Gemini (Google)
  4. Learn prompt engineering — The skill that turns basic calls into powerful features

Want to go deeper? My AI Integration Engineer course takes you from these basics to building production-ready AI features—the skills that are in high demand right now.


Complete Working Example

Here's everything in one file—copy, paste, and run:

import OpenAI from 'openai'
import 'dotenv/config'
 
const openai = new OpenAI()
 
// Basic call
async function basicCall() {
  const response = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user', content: 'Explain recursion in one sentence.' }
    ]
  })
  console.log('Basic:', response.choices[0].message.content)
  console.log('Tokens used:', response.usage?.total_tokens)
}
 
// Streaming call
async function streamingCall() {
  console.log('\nStreaming:')
  const stream = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [
      { role: 'user', content: 'Write a one-line joke about APIs.' }
    ],
    stream: true
  })
 
  for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content || '')
  }
  console.log('\n')
}
 
// Run both
async function main() {
  try {
    await basicCall()
    await streamingCall()
  } catch (error) {
    if (error instanceof OpenAI.APIError) {
      console.error(`API Error: ${error.status} - ${error.message}`)
    } else {
      throw error
    }
  }
}
 
main()

You're no longer someone who reads about AI. You're someone who builds with it.

In the next post, we'll compare the major AI providers—OpenAI, Anthropic, and Google—so you know which model to use for what.

0claps
Frank Atukunda

Frank Atukunda

Software Engineer documenting my transition to AI Engineering. Building 10x .dev to share what I learn along the way.

Share this article

Get more like this

Weekly insights on AI engineering for developers.

Comments (0)

Join the discussion

Sign in with GitHub to leave a comment and connect with other engineers.

No comments yet. Be the first to share your thoughts!