Your First AI Call: The Foundation of Everything (Part 1/7)
This is Part 1 of a 7-part series on AI Fundamentals. Follow along to build a complete understanding of how AI applications actually work.
Last month I was called in to help fix a client’s AI application.
It wasn’t working. Worse, nobody on the team understood why.
The codebase was a mess of framework abstractions. Prompts buried in config files. “Memory systems” they couldn’t debug. The entire team was stuck, burning client budget trying to figure out why their “AI agent” kept failing.
Then I realized: they never learned the fundamentals.
They plugged prompts into a framework, then tried to rig it, and hoped it would work. When it didn’t, they had no idea where to look or what was actually happening under the hood.
So I showed them the concepts, the same ones I’m about to share with you. No framework. Just pure API calls. All of a sudden, the breakthrough. They understood what was happening. They were able to fix the application.
This is the first article in a 7-part series covering the AI fundamentals I wish they’d known - and honestly, what I wish I’d known when I started building AI applications two years ago.
The Truth About AI Applications
Here’s what most developers don’t realize: you don’t need a framework to talk to Claude or GPT.
You need a few lines of code.
That’s it. That’s an AI application.
Everything else - RAG systems, AI agents, chatbots, content generators, all of it - is just orchestration built on this foundation.
Let me show you.
Your First API Call to Claude
Here’s the complete, working code for your first AI application. I’ll be using the Anthropic API to demonstrate, but the same principles apply to OpenAI (keep reading for that example).
import os
from anthropic import Anthropic
from dotenv import load_dotenv
load_dotenv()
client = Anthropic(api_key=os.getenv(”ANTHROPIC_API_KEY”))
response = client.messages.create(
model=”claude-sonnet-4-20250514”,
max_tokens=1024,
messages=[{”role”: “user”, “content”: “Explain what an API is in one sentence.”}],
)
answer = response.content[0].text
print(answer)Run this code, and Claude responds:
“An API is an interface that allows different software systems
to communicate with each other.”Congratulations. You just built an AI application.
Breaking Down The Pattern
Let’s examine what’s actually happening here, because this pattern is the foundation for everything you’ll build.
Step 1: Import and Initialize
import os
from anthropic import Anthropic
from dotenv import load_dotenv
load_dotenv()
client = Anthropic(api_key=os.getenv(”ANTHROPIC_API_KEY”))The Anthropic SDK is just a thin wrapper around HTTP requests. Nothing magic. You’re creating a client that knows how to talk to Anthropic’s API servers.
It goes without saying that you should never hardcode your API key in the code. Use environment variables instead.
Step 2: Call the API
response = client.messages.create(
model=”claude-sonnet-4-20250514”,
max_tokens=1024,
messages=[{”role”: “user”, “content”: “Explain what an API is in one sentence.”}],
)This is the fundamental pattern you’ll use everywhere. Let’s break down each parameter:
model - Which version of Claude you’re using.
max_tokens - Maximum length of Claude’s response. This is NOT your input length - it’s how long Claude’s answer can be. Think of it as a word limit. 1024 tokens is approximately 750 to 1000 words, as the common rule of thumb is that one token is about 3/4 of a word.
messages - This is your conversation. It’s an array of message objects, each with:
role- Either “user” (you) or “assistant” (Claude)content- The actual text
Right now we’re sending one message. In the next article, we’ll see how sending multiple messages creates conversation memory.
Step 3: Extract the Response
answer = response.content[0].text
print(answer)The response object contains everything Claude sent back. For simple text responses, you want response.content[0].text.
Why the [0]? Because Claude’s response is technically a list of content blocks. For text-only responses, there’s just one block. Later in this series, we’ll see responses with multiple blocks when Claude uses tools.
Understanding the Response Object
Let’s look at what else comes back in the response:
print(f”Model used: {response.model}”)
print(f”Stop reason: {response.stop_reason}”)
print(f”Input tokens: {response.usage.input_tokens}”)
print(f”Output tokens: {response.usage.output_tokens}”)model - Confirms which model actually processed your request
stop_reason - Why Claude stopped generating. Usually “end_turn” (Claude finished naturally), but could be:
“max_tokens”- Hit your max_tokens limit“stop_sequence”- Hit a stop sequence you defined“tool_use”- The LLM wants to use a tool
usage - Token counts for cost tracking. This is critical for production applications:
Input tokens: Your prompt
Output tokens: Claude’s response
The Complete Working Example
Here’s the full code with proper error handling and environment setup:
“”“
Your First Claude API Call - The Foundation
“”“
import os
from anthropic import Anthropic
from dotenv import load_dotenv
load_dotenv()
client = Anthropic(api_key=os.getenv(”ANTHROPIC_API_KEY”))
response = client.messages.create(
model=”claude-sonnet-4-20250514”,
max_tokens=1024,
messages=[{”role”: “user”, “content”: “Explain what an API is in one sentence.”}],
)
answer = response.content[0].text
# Extract and display the response
print(”=” * 80)
print(”CLAUDE’S RESPONSE:”)
print(”=” * 80)
print(answer)
print(”=” * 80)
# Display metadata
print(”\nRESPONSE METADATA:”)
print(f”Model used: {response.model}”)
print(f”Stop reason: {response.stop_reason}”)
print(f”Input tokens: {response.usage.input_tokens}”)
print(f”Output tokens: {response.usage.output_tokens}”)What About OpenAI?
The beautiful thing about learning these fundamentals is that they transfer between providers. Once you understand the Claude API, the OpenAI API is nearly identical.
Here’s the equivalent OpenAI code:
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv(”OPENAI_API_KEY”))
response = client.chat.completions.create(
model=”gpt-4o”,
max_tokens=1024,
messages=[{”role”: “user”, “content”: “Explain what an API is in one sentence.”}],
)
answer = response.choices[0].message.content
# Extract and display the response
print(”=” * 80)
print(”GPT’S RESPONSE:”)
print(”=” * 80)
print(answer)
print(”=” * 80)
# Display metadata
print(”\nRESPONSE METADATA:”)
print(f”Model used: {response.model}”)
print(f”Finish reason: {response.choices[0].finish_reason}”)
print(f”Input tokens: {response.usage.prompt_tokens}”)
print(f”Output tokens: {response.usage.completion_tokens}”)
print(f”Total tokens: {response.usage.total_tokens}”)Key Differences Between Anthropic and OpenAI APIs
Method names:
Anthropic:
client.messages.create()OpenAI:
client.chat.completions.create()
Response structure:
Anthropic:
response.content[0].textOpenAI:
response.choices[0].message.content
Token usage:
Anthropic:
response.usage.input_tokens/output_tokensOpenAI:
response.usage.prompt_tokens/completion_tokens
Stop reason naming:
Anthropic:
response.stop_reason→ values:“end_turn”,“max_tokens”,“stop_sequence”, “tool_use”OpenAI:
response.choices[0].finish_reason→ values:“stop”,“length”,“content_filter”, “tool_calls”
But the core concept is identical: send a messages array, get a response back.
Why This Matters
Understanding this fundamental pattern changes everything. Many developers jump straight into using frameworks and libraries, but those are simply layers built on top of the same basic API interactions.
Without understanding the foundation, you’re building on sand - and when something breaks, you won’t know where to look.
Frameworks are tools. In many cases, they’re useful, sometimes overkill. But if you don’t understand what they’re doing underneath, you’re just hoping things work.
Now you understand the foundation. Everything we build in this series - conversation memory, tool calling, RAG systems, streaming responses - is built on this exact pattern.
Try It Yourself
Here’s what to do next:
Get your API keys:
Anthropic: https://console.anthropic.com
OpenAI: https://platform.openai.com
Create a
.envfile:
ANTHROPIC_API_KEY=your_anthropic_key_here
OPENAI_API_KEY=your_openai_key_hereInstall the libraries:
pip install anthropic openai python-dotenvRun the code and experiment:
Try different prompts
Compare Claude vs GPT responses
Watch the token usage and calculate costs
What’s Next
In the next article, we’ll tackle the mystery of “conversation memory.”
It turns out, what many frameworks call “memory management” often starts with something as simple as a Python list.
By learning this yourself, you’ll understand both the simplicity and the power behind those more advanced tools.
This is Part 1 of a 7-part series on AI Fundamentals. Follow along to build a complete understanding of how AI applications actually work. All code examples are available in the GitHub repository.


