Lesson 10 of 16 · Level 3: Advanced

How to Use an AI API with Python: From Your First Call to Processing Thousands of Texts

  • ⏱ 14 min read
  • ❓ 4 review questions
  • ✍️ Exercise with solution
  • 📥 Downloadable template
In this lesson
  1. What an API is and how it's billed
  2. Setup: account, key and library
  3. Your first call
  4. A conversation with memory
  5. Batch processing: classifying a whole CSV
  6. Controlling costs
  7. Checking the quality of the output
  8. Summary
What you'll learn
  • Understand what an AI model's API is, how it's billed and when it makes sense to use it.
  • Make your first call from Python and store your key securely.
  • Keep a conversation going with history from your own program.
  • Process hundreds of texts from a CSV automatically while controlling errors and cost.
  • Measure the quality of an automated process before you trust it.
📥 Practice this lesson

This is the file the classify.py script in this lesson expects. Save it in the same folder as the script.

Chat apps are perfect for one task at a time. But to classify 2,000 customer comments or extract data from 500 invoices, copy and paste stops working. That's what language model APIs are for: using AI from your own code to process large volumes automatically.

$1.20to classify 1,000 reviews with Claude Sonnet 5.5 at November 2026 prices (calculation below)
−50%discount from Anthropic's Batch API if you can wait for the results
20 rowsof testing before running any full file: the rule that saves the most money

This lesson uses Python. If you've never programmed, read it to understand how it works and come back after our Python for data analysis lesson, which covers the basics you'll need.

What an API is and how it's billed

An API (application programming interface) is a doorway that lets one program talk to another. Instead of typing into a chat window, your program sends the message over the internet to the provider (Anthropic, OpenAI, Google and others), the model processes it and the answer comes back to your program as data.

ChatChatGPT, Claude, Gemini…
Use
Manual conversation.
Price
Free or a monthly subscription.
Volume
One task at a time.
Best for
Daily work, varied tasks.
Day to day
APIFrom your code or systems
Use
Your program sends and receives the messages.
Price
Pay as you go, per token processed.
Volume
Thousands of automated tasks.
Best for
Repetitive processes, integrations, products.
Scale

Remember from lesson 2 that models work in tokens. With an API you pay for the tokens you send (input) and the tokens the model generates (output), which usually cost several times more. More powerful models cost more; smaller ones are much cheaper and faster.

Setup: account, key and library

  1. Create a developer account in the provider's console and add a payment method. This lesson uses the Claude API (Anthropic); OpenAI's and Google's work similarly.
  2. Set a monthly spending limit: your safety net if a program loops.
  3. Generate an API key. Treat it like a password: anyone who has it can spend your money.
  4. Install the official library in your virtual environment: pip install anthropic

Store the key in an environment variable

Never write the key into your code: it would end up on GitHub or in a screenshot. Store it in an environment variable, which the library reads automatically:

# Windows (PowerShell), for the current session
$env:ANTHROPIC_API_KEY="your-key-here"

# macOS and Linux
export ANTHROPIC_API_KEY="your-key-here"
If your key leaks

Revoke it in the console, create a new one and check recent usage. If you use Git, add files with keys, such as .env, to .gitignore.

Your first call

# first_message.py
import anthropic

client = anthropic.Anthropic()   # reads the key from ANTHROPIC_API_KEY

response = client.messages.create(
    model="claude-sonnet-5-5",     # check the current models in the docs
    max_tokens=500,
    system="You are an assistant who answers briefly and clearly.",
    messages=[
        {"role": "user", "content": "Explain what an API is in 3 sentences."}
    ],
)

print(response.content[0].text)
print("Tokens:", response.usage.input_tokens, "input,",
      response.usage.output_tokens, "output")

Expected result: three sentences explaining what an API is and, below them, a line with that call's input and output tokens. If you get an authentication error instead, the environment variable isn't set in the terminal where you're running the script.

The key parameters:

  • model: in November 2026, claude-sonnet-5-5 is the current Sonnet and claude-haiku-5-5 the most economical option. Names change with new versions; check the documentation.
  • max_tokens: the most tokens it may generate, which caps length and cost.
  • system: permanent instructions, like those of the custom assistant in lesson 8.
  • messages: the conversation, each message with its role (user or assistant).

The text comes back in response.content[0].text and the usage in response.usage, so you can price every call.

Other providers

OpenAI (pip install openai) and Google (pip install google-genai) follow the same logic with a few different parameter names. Everything else in this lesson applies unchanged.

1. Where should you store your API key?

  • In a variable inside the script so you don't forget it.
  • In an environment variable, outside the code.
  • In a comment at the top of the file.

The key unlocks your paid account. If it's in the code, it leaks the moment you share the file.

A conversation with memory

The API doesn't remember anything between calls: each one is independent. To keep a conversation going, your program has to send the full history every time. That's how every chat app works under the hood:

# chat.py
import anthropic

client = anthropic.Anthropic()
history = []

while True:
    question = input("You: ").strip()
    if question.lower() in ("quit", "exit", ""):
        break
    history.append({"role": "user", "content": question})

    response = client.messages.create(
        model="claude-sonnet-5-5",
        max_tokens=800,
        system="You are a personal finance tutor. Answer with U.S. examples.",
        messages=history,
    )
    text = response.content[0].text
    history.append({"role": "assistant", "content": text})
    print(f"\nAI: {text}\n")

Notice the consequence: every new message resends the whole conversation, so long conversations use more and more input tokens. It's the same "context window" from lesson 2, now with a visible price tag.

Batch processing: classifying a whole CSV

This is the use case with the biggest return. We start with customer-reviews.csv, which has two columns, id and review, and we want to add a sentiment, a topic and a summary to each row. We combine what you saw in lesson 5 (JSON outputs) with file handling and error handling:

# classify.py
import csv
import json
import time

import anthropic

MODEL = "claude-sonnet-5-5"
TOPICS = {"Price", "Service", "Shipping", "Quality", "Other"}

client = anthropic.Anthropic(max_retries=3)   # retries only on temporary errors

INSTRUCTIONS = """You classify customer reviews for an online store.
Reply ONLY with valid JSON, no extra text, in this shape:
{"sentiment": "Positive|Negative|Mixed", "topic": "Price|Service|Shipping|Quality|Other", "summary": "12 words max"}"""


def classify(review):
    response = client.messages.create(
        model=MODEL,
        max_tokens=200,
        system=INSTRUCTIONS,
        messages=[{"role": "user", "content": f"<review>{review}</review>"}],
    )
    text = response.content[0].text.strip()
    # In case the model wraps the JSON in a code block
    text = text.removeprefix("```json").removeprefix("```").removesuffix("```").strip()
    data = json.loads(text)
    if data.get("topic") not in TOPICS:   # validate: never trust blindly
        data["topic"] = "REVIEW"
    usage = response.usage.input_tokens + response.usage.output_tokens
    return data, usage


def main():
    with open("customer-reviews.csv", newline="", encoding="utf-8") as f:
        rows = list(csv.DictReader(f))

    results, tokens = [], 0
    for i, row in enumerate(rows, start=1):
        try:
            data, usage = classify(row["review"])
            tokens += usage
        except json.JSONDecodeError:
            data = {"sentiment": "REVIEW", "topic": "REVIEW", "summary": "Invalid response"}
        except anthropic.APIError as e:
            print(f"Row {i}: API error ({e.__class__.__name__}), flagged for review")
            data = {"sentiment": "REVIEW", "topic": "REVIEW", "summary": ""}
        results.append({**row, **data})
        print(f"{i}/{len(rows)} · {data['topic']}")
        time.sleep(0.5)   # short pause so you don't hit rate limits

    with open("reviews_classified.csv", "w", newline="", encoding="utf-8-sig") as f:
        writer = csv.DictWriter(f, fieldnames=list(results[0].keys()))
        writer.writeheader()
        writer.writerows(results)

    print(f"Done: {len(results)} reviews · {tokens} tokens used")


if __name__ == "__main__":
    main()

Expected result: a file called reviews_classified.csv with the original columns plus sentiment, topic and summary, and a final line reading "Done: 20 reviews" followed by the token count. A typical row:

4,The bag arrived torn but they replaced it fast,Mixed,Service,Damaged bag replaced quickly by the store

The design choices that make the script reliable

  • Exact format and closed categories, so you can analyze the output in Excel or pandas.
  • Validation: a topic outside the list is flagged "REVIEW," never accepted.
  • Handled errors: invalid JSON or a connection failure flags the row instead of stopping the run.
  • Retries and pauses to ride out temporary errors and rate limits.
  • Token tracking, so you know what each run cost.
  • utf-8-sig, so Excel shows accents and emoji correctly.

2. The model returns the topic "Packaging," which isn't in your list. What does the script do?

  • It stops with an error.
  • It saves "Packaging" as a new category.
  • It flags the topic as "REVIEW" so a person can check it.

Validation keeps unexpected answers from quietly contaminating your results.

Controlling costs

Before processing thousands of rows, estimate the cost with a small test. An example using the prices Anthropic published in November 2026 for Claude Sonnet 5.5: $2 per million input tokens and $10 per million output tokens (prices change, so always check the official pricing page):

ItemCalculationResult
Input tokens (1,000 reviews × 300)300,000 × $2 / 1,000,000$0.60
Output tokens (1,000 reviews × 60)60,000 × $10 / 1,000,000$0.60
Total$1.20

Tokens vs. cost

Input tokens300k
Output tokens60k
Input cost$0.60
Output cost$0.60

Output is only 20% of the tokens but costs as much as the input, because each output token is five times more expensive. That's why limiting max_tokens and asking for short answers saves money.

By hand, a thousand reviews could take a full day. Before running a large batch, tick off this list:

Personal and confidential data

Using the API doesn't remove the obligations from lesson 12: read the provider's data-use terms, anonymize when you can (remove names, Social Security and account numbers, phone numbers) and comply with the privacy laws that apply to your customers before sending their information.

Checking the quality of the output

A process that's wrong 10% of the time can be very useful or a disaster, depending on what you decide with it. Measure before you trust it:

  1. Classify 50 rows by hand (your "answer key") and compare them with the script's output.
  2. Study the errors: a missing category? Ambiguous cases? Would examples in the instructions help (lesson 5)?
  3. Adjust the instructions and measure again on the same sample.
  4. Once it's running, review every "REVIEW" row plus a random sample regularly.

3. You're going to process 20,000 invoices for the first time. What do you do first?

  • Test a small sample, review the results, estimate the cost and set a spending limit.
  • Run the script with the most powerful model to guarantee quality.
  • Run all 20,000 and review the errors at the end.

A small test tells you whether the prompt works and what the full run will cost, before you spend time and money.

4. The batch of 1,000 reviews costs $1.20 through the standard API. If you send it through the Batch API with a 50% discount, how much do you pay?

  • $1.20, because the discount only applies to input
  • $0.30
  • $0.60

Anthropic's batch discount applies to both input and output: $1.20 × 50% = $0.60. In exchange, the results don't come back instantly.

Practice exercise: an order-data extractor

Modify classify.py so it processes a CSV of customer requests (column message) and extracts these columns: product_name, quantity (a number or empty), urgent (yes/no) and needs_human (yes/no). Test it on 10 messages you write yourself, including two that have nothing to do with orders.

See solution
INSTRUCTIONS = """You extract data from customer order messages.
Reply ONLY with valid JSON in this shape:
{"product_name": "text or null", "quantity": number or null,
 "urgent": "yes|no", "needs_human": "yes|no"}
Rules:
- Use null if the data isn't in the message. Don't guess quantities.
- urgent = "yes" only if the customer mentions a close date or the word urgent.
- needs_human = "yes" if it's a complaint, a question that isn't an order,
  or the message is ambiguous."""


def validate(data):
    if data.get("urgent") not in ("yes", "no"):
        data["urgent"] = "REVIEW"
    if data.get("needs_human") not in ("yes", "no"):
        data["needs_human"] = "REVIEW"
    qty = data.get("quantity")
    if qty is not None and not isinstance(qty, (int, float)):
        data["quantity"] = "REVIEW"
    return data

# In classify(): replace the "topic" check with
#     data = validate(json.loads(text))
# and in main() read row["message"] instead of row["review"].

Check that the two non-order messages come back with an empty product_name and needs_human = "yes". validate() is strict on purpose: a capitalized "Yes" or a quantity like "two" gets flagged "REVIEW."

Summary

  • The API lets you use models from your own code, paying per input and output token.
  • Keep the key in an environment variable and set a spending limit.
  • messages.create takes the model, the token limit, the instructions (system) and the messages.
  • The API has no memory: to hold a conversation, send the full history.
  • For batch work: exact format, validation, handled errors, a small test first and measured quality.

Next lesson: How to Implement AI in a Business: Use Cases, ROI, Pilot and Policy. You'll move from your own projects to the organization, from choosing use cases to measuring the return.

🎓 Save your progress and get a free certificate

Create your account in 30 seconds, mark your lessons and download your certificate at the end.

Enroll for free