AiCore logo

Lesson 1 — AI APIs and Your First Service Call

Module 5, Unit 3 | Lesson 1 of 3

By the end of this lesson, you will be able to:

  • Describe the structure of a REST API call to an LLM service (K8, S25)
  • Write Python code to make your first authenticated API call, send a structured prompt, and parse the response (S25)
  • Monitor token usage and calculate estimated cost per call (S25)

Why this unit is different

Units 1 and 2 used the Gemini API to explore LLM concepts and evaluate platforms. Unit 3 moves to the OpenAI API — the most widely adopted API for production AI development — because the tool calling patterns, cost tracking, and defensive coding in Units 3 and 4 all use OpenAI conventions that the reviewer will expect to see in the final architecture.

Unit 3 is the most hands-on unit in Module 5. Every lesson includes a coding activity, and the code you write here becomes the foundation you extend in Units 4, 5, and beyond. You will write real Python, call real APIs, and produce working code that goes into your GitHub repository.

Write it clearly and commit it properly.

Why this skill matters beyond your main project:

  • Every AI integration you ever build — whether it is a simple chatbot, a document processor, or a multi-agent workflow — starts with an API call. Getting this right once means you have a pattern you can reuse forever.
  • Being able to write, debug and explain a working API integration puts you in a fundamentally different category from someone who can only use AI tools built by others.

How AI APIs work

A REST API call to an LLM service is a standard HTTP request with a JSON body. The pattern is the same across providers — only the specific fields change.

Your code sends a request to a URL. The request includes your API key for authentication and a JSON body describing what you want. The server runs your prompt through the model and sends back a JSON response containing the generated text, how many tokens were used, and why the model stopped generating.

That exchange — request in, response out — is everything. The SDK handles the HTTP mechanics so your code never has to deal with raw HTTP headers directly, but knowing what is happening underneath makes you a better debugger.

The request

Every request to a chat-based LLM API contains three things:

The model — which model to use. This is a decision with cost, speed and capability implications. gpt-4o-mini is fast and cheap. gpt-4o is more capable and more expensive. You choose per call.

The messages array — the conversation history, formatted as a list of objects. Each object has a role and content. The roles are:

  • system — your instructions to the model. This is where you define its behaviour, constraints, persona and task. The model reads this before anything else.
  • user — the input from the person or process triggering the call.
  • assistant — previous model responses, if you are maintaining conversation history across turns.

This is why it is called "chat completions" — the API is designed around a conversation format, even when you are using it for a single-turn task like classification or summarisation.

The parameters — optional controls over the response:

  • temperature — controls randomness. 0.0 gives deterministic, consistent output. 1.0 gives more varied, creative output. For structured tasks like extraction or classification, use a low value (0.0–0.3). For creative tasks, higher values are appropriate.
  • max_tokens — a hard cap on the response length. Set this deliberately. If you need a short label, cap it low. If you need a full document summary, give it room.

The response

The response object contains more than just the text. The fields you will use most:

response.choices[0].message.content   # the generated text
response.choices[0].finish_reason     # why the model stopped: "stop", "length", or "tool_calls"
response.usage.prompt_tokens          # tokens in your request
response.usage.completion_tokens      # tokens in the response
response.usage.total_tokens           # sum — this is what you are billed on

finish_reason matters in production. If it says "length", the model hit max_tokens before it finished — your response is truncated. If it says "stop", the model reached a natural end point. If it says "tool_calls", the model wants to call a function (covered in Lesson 2).

🔑 Key term — API key: A secret credential that identifies your account when making requests to an AI service. Treat it like a password. Never hardcode it in your code — always load it from an environment variable.

🔑 Key term — Temperature: A parameter that controls the randomness of model outputs. At 0, the model consistently picks the most probable next token. As temperature rises, less probable tokens become more likely, producing more varied output. Most production tasks work best between 0 and 0.5.

Setting up securely

Getting your API key

Before you can make an API call, you need an OpenAI API key:

  1. Go to platform.openai.com and sign in or create an account.
  2. Navigate to API keys in the left sidebar (or go to platform.openai.com/api-keys directly).
  3. Click Create new secret key, give it a name (e.g. "Module 5"), and copy the key immediately — you cannot view it again.
  4. Note that API usage has a small cost. OpenAI provides some free credit for new accounts; check your usage dashboard at platform.openai.com/usage.

Before you write a single line of API code, set up your environment properly:

# Install required packages
# pip install openai python-dotenv

# Create a .env file in your project root:
# OPENAI_API_KEY=your-key-here

# Load in your Python file:
from dotenv import load_dotenv
import os

load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")

Add .env to your .gitignore immediately. A leaked API key is a billing liability and a security incident.

Your first API call

from openai import OpenAI
from dotenv import load_dotenv
import os

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Summarise the main risks of deploying AI in a customer-facing context in three bullet points."}
    ],
    temperature=0.3,
    max_tokens=300
)

# The response text
print(response.choices[0].message.content)

# Token usage
print(f"Prompt tokens: {response.usage.prompt_tokens}")
print(f"Completion tokens: {response.usage.completion_tokens}")
print(f"Total tokens: {response.usage.total_tokens}")

A note on errors: API calls can fail — rate limits, network issues, and invalid keys are the most common causes. In production code you would wrap this call in a try/except block catching RateLimitError and APIConnectionError (both importable from openai). You will build that pattern in Lesson 2. For now, if you get an error, read the message carefully — it almost always tells you exactly what went wrong.

Run this, read the output, and then look at the raw response object. Understanding what is in it — not just what you extracted — is part of building reliable systems.


Activity — First API call

  1. Set up a Python project with a virtual environment and a .env file
  2. Write the code above (or equivalent for your chosen provider — Anthropic, Google)
  3. Run it successfully and capture the output
  4. Modify the system prompt to be relevant to your workplace project
  5. Commit your working code to your GitHub repository

Add to your Commit Log: your chosen model, a screenshot of the working output, and a one-paragraph note on what you would change about the system prompt after seeing the response.

Coach Cora

Coach Cora

If your code does not run, that is expected — debugging is a core developer skill, not a sign something has gone wrong. Read the error message carefully, search for the specific error text, and fix one thing at a time. Every error you solve makes the next one easier.

Checklist

  • My Python environment is set up and dependencies are installed
  • My API key is stored in a dotenv file — not hardcoded in the script
  • The dotenv file is listed in gitignore so it will never be committed
  • My first API call runs and I can read the generated text from the response
  • I can read the prompt tokens, completion tokens and total tokens from the response
  • I understand what finish_reason tells me and when it would say "length" instead of "stop"
  • I have modified the system prompt to be relevant to my workplace project and observed the difference
  • My working code is committed to GitHub and linked in my Commit Log

A developer commits their Python project to a public GitHub repository and realises their OpenAI API key was hardcoded in the script. What should they do first?


KSB evidence focus

  • S25 — Keep up to date with existing, evolving, emerging technologies and sector trends in AI, automation and technology including methods to evaluate vendor and supplier solutions. Making a working API call to an LLM service — setting up authentication, structuring the request, and reading the response — is the practical foundation of S25. Your code is your evidence.

  • K8 — This lesson is a direct encounter with third-party solution implications: API keys, data leaving your environment, token costs and rate limits are all K8 considerations made real through the code you write.


Up next: Lesson 2 extends your API integration to include tool calling — the mechanism that lets an LLM trigger real actions in your code.