Foundations

Every concept the course assumes — terminal, APIs, webhooks, git.

What a terminal and shell are

A terminal is a window that lets you type commands instead of clicking. A shell is the program inside it that reads what you typed and runs it. That's the entire mental model.

On a Mac the default shell is zsh. On a fresh Windows machine with WSL2 installed, you get Ubuntu's bash. Both speak the same handful of commands this course uses. You can live your whole agency career on six of them.

The six commands you actually need

zsh — the six-command tour
~pwd
/Users/you
~ls
Desktop Documents Downloads Library
~cd Documents
Documentsmkdir client-a
Documentscd client-a
client-atouch notes.md
  • pwd— “print working directory.” Where am I?
  • ls— list what's in this directory.
  • cd <path> — change directory. cd .. goes up one; cd ~ goes home.
  • mkdir <name> — make a new folder.
  • touch <file> — create an empty file.
  • cat <file> — print a file to the screen.

PATH — how the shell finds programs

When you type git, the shell searches a list of folders called PATH in order and runs the first git binary it finds. Homebrew adds /opt/homebrew/bin to your PATH so brew- installed tools are findable. If a fresh install “doesn't work,” 80% of the time the fix is adding the tool's install folder to PATH and reopening the terminal.

bashzsh · print PATH
echo $PATH
# /opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

Environment variables

Variables the shell exposes to every program it launches. API keys live here. export ANTHROPIC_API_KEY=sk-... puts your key in the current shell; putting the same line in ~/.zshrc makes it permanent.

What Claude is vs ChatGPT vs other LLMs

A large language model (LLM) is a program that takes text in and produces text out. That's the whole category. Claude, ChatGPT's GPT-4o and o-series, Google's Gemini, xAI's Grok, Meta's Llama — they are all LLMs. They differ in training data, architecture, context window, and, crucially for agency work, in how agentically they can be driven.

Why this course is all Claude

Claude, made by vendorAnthropic, is the one with a first-party agent CLI (Claude Code) designed to read your filesystem, run shell commands, edit files, and hold a task through many turns. That's the mode we use. ChatGPT has tool use too, but Claude Code is what ships this course's deliverables — it's purpose-built for coding agents, and that advantage compounds across the whole agency stack.

The current Claude model family

Default for this course

Claude Opus 4.7

Flagship reasoning model. 1M-token context window. Knowledge cutoff January 2026. This is what claw runs by default and what every phase of this course is built on.

Balanced

Claude Sonnet 4.6

Faster and cheaper than Opus, still strong. Good for high- volume tasks where you don't need the absolute ceiling. Supports extended + adaptive thinking.

Speed

Claude Haiku 4.5

Smallest current model. Fast and cheap. Useful for classification, routing, and simple extraction at scale.

Legacy

Opus 4.6, Sonnet 4.5, and earlier

Still available via API for migration windows, but Anthropic recommends upgrading. Claude Opus 4 (base) and Sonnet 4 (base) are scheduled to retire 2026-06-15.

What you're actually paying for

Two billing models to know about. The Claude Code subscription (Pro / Max) flat-rates sessions in Cursor and on the CLI — this is the path 90% of this course assumes. The anthropicClaude API bills per input/output token and is what your own apps (Tab 7) will call programmatically. Same underlying models, different wallets.

What Claude Code is

Claude Code is an agentic coding tool — not a chat window. You hand it a task, and it reads files, runs commands, writes code, tests what it wrote, and reports back. Treating it like ChatGPT will waste your session. Treating it like a junior engineer with perfect recall of your repo will ship real work.

Where it runs

CLI

Terminal (this course's default)

Launch with the claw alias. Full filesystem access, full shell access, long sessions.
IDE

Cursor integration

Runs as a terminal pane inside Cursor. Claude Code sees the whole project through the same shell it would use standalone, and you watch it edit your files in-editor.
Web

claude.ai/code

Browser version for quick tasks without a local project. No filesystem write access — purely an assistant, not an agent.
Mobile

Desktop / mobile apps

Ship work from anywhere. Useful for approving long-running tasks you kicked off from your laptop.

The mental shift from chatbots

In a chatbot you ask a question and get an answer. In Claude Code you give a goal and a set of constraints, and Claude decides which files to read, which commands to run, which tests to execute. Your job is to specify clearly and verify what came back — not to direct each keystroke.

This is the single biggest adjustment for people arriving from ChatGPT. The productive tone is closer to writing a Jira ticket than having a conversation. Tab 4 drills into the exact anatomy of a good prompt.

First-session sanity check

claw — first session
~/Documents/client-aclaw
Welcome to Claude Code · opus 4.7 · effort max
yousummarise every markdown file in this directory
Reading notes.md · brief.md · 2 more… producing a summary…

What Cursor is

Cursor is a code editor forked from VS Code with AI baked into the window. For this course, it's mostly the terminal host where Claude Code runs, plus a few inline-edit tricks you'll use without thinking about them.

The three panes you live in

  • File tree(left) — what files exist. Click any file to open it. Cursor and Claude Code both read the whole tree; you don't have to babysit which files are “in scope.”
  • Editor(center) — where you see and edit files. Claude Code's edits appear here as Claude applies them. You can accept, reject, or tweak.
  • Terminal (bottom, Ctrl+`) — where clawruns. Everything in Tab 2 works the same whether you're in Cursor's terminal pane or your system terminal.

Cursor vs Claude Code — when to use which

Cursor built-in AI

Small edits

Cmd+K to rename a variable across a file, tighten a CSS block, rewrite a copy paragraph. Fast chat-style in-editor tweaks.

Claude Code

Real work

Multi-file changes, scaffolds, migrations, anything that needs planning, testing, or running the code. claw in the terminal pane is the default.

Extensions worth installing

Cursor inherits VS Code's extension marketplace. The ones this course leans on:

  • ESLint + Prettier — catches errors and formats on save.
  • Tailwind CSS IntelliSense — autocompletes class names in the Next.js work in Tabs 7–8.
  • GitLens— blame annotations and inline commit history. Makes it easy to ask Claude “why did this line get added?”

What an API is

An API (Application Programming Interface) is a contract that lets one program ask another program to do something. In 2026 that almost always means one program sends an HTTP request to a URL, and the other program sends back JSON. That's 95% of what you need to hold in your head.

your codeNext.js API routeClaude Code CLIplatform APIGHL · Fathom · Stripeapi.example.comPOST /v1/contactsAuthorization: Bearer … · body: JSON201 Createdbody: {"id":"ct_01H…"}HTTP request / response cycleone round trip · usually < 500ms · JSON both ways

Anatomy of a request

  • URL — the endpoint. Example: https://api.fathom.ai/external/v1/meetings.
  • MethodGET to read, POST to create, PATCH to update, DELETE to remove. Servers use this to route.
  • Headers — metadata. Most importantly Authorization (your key) and Content-Type (usually application/json).
  • Body — the data you're sending on POST/PATCH. JSON.

Anatomy of a response

  • Status code— 200s = success, 400s = you sent something wrong, 500s = the server broke. 401 = your key is bad. 429 = you're hitting them too fast. Memorize these four.
  • Headers — rate-limit counters, pagination cursors, signatures.
  • Body — JSON with what you asked for.

Make your first request

bashTerminal · curl
curl -i https://httpbin.org/get
# HTTP/2 200
# content-type: application/json
# { "args": {}, "headers": {...}, "url": "https://httpbin.org/get" }

No auth needed — sandboxhttpbin.org is a public testing sandbox. -i prints the headers so you can see the status code. Try a few of the other routes (/post, /status/404) to feel what different responses look like before you wire a real API.

What a webhook is

An API is you calling the platform. A webhook is the platform calling you. When Fathom finishes processing a meeting, it sends a POST request to a URL you registered, and now your server has to handle it. The critical twist is that anyone on the internet can also send a POST to that URL — so you have to verify the call really came from Fathom.

webhook with HMAC-SHA256 verificationplatformFathom · GHL · Typeformhmac = HMAC_SHA256(secret, rawBody)your serverNext.js API routeexpected = HMAC_SHA256(secret, rawBody)POST /webhooks/fathombody + X-Signature-256: hmactimingSafeEqual(expected, signature)match → process · mismatch → 401

The signature ritual

The platform and you share a secret. When they send a webhook, they also send a header like X-Signature-256 containing an HMAC-SHA256 of the raw body using that secret. Your job: hash the raw body with the same secret, compare using a constant-time function, reject if they don't match.

typescriptTS · webhook verify
import crypto from "node:crypto";

export function verifyWebhook(
  rawBody: string,
  signatureHeader: string | null,
  secret: string,
): boolean {
  if (!signatureHeader) return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  const a = Buffer.from(expected, "hex");
  const b = Buffer.from(signatureHeader.replace(/^sha256=/, ""), "hex");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Three things that trip people up

  • Hash the raw body, not the parsed JSON. If your framework parses the body before you see it, the bytes you hash are different from the bytes the platform hashed — the check fails 100% of the time. In Next.js API routes, read the body as text first, verify, then JSON.parse.
  • Use timingSafeEqual, not ===. Plain string equality leaks timing information that an attacker can use to guess the signature byte-by-byte.
  • Respond in under a few seconds.Most platforms retry if you're slow. Do expensive work — Claude calls, database writes — in a background job; the webhook handler just verifies, enqueues, and returns 200.

What a model is — tokens, context, reasoning

A model is a giant statistical function that takes a sequence of tokens and predicts the next one. “Reasoning” is the model generating an internal chain of those predictions before giving you the final answer. Everything else is accounting — counting the tokens you send in, counting the ones that come back, and watching the window in between.

Tokens

Text is chopped into chunks called tokens. Rough rule: 1 token ≈ 4 characters of English ≈ ¾ of a word. “Hello world” is 2 tokens. A 1,000-word document is ~1,300 tokens. You pay per token on the API, and every model has a maximum number of tokens it can handle in one request — that's the context window.

Context window

Opus 4.7's context window is 1,000,000 tokens — roughly half a million words. Every message you've sent, every file Claude read, every command it ran and the output it saw, all count against that ceiling. When you cross the high-water mark, Claude Code triggers compaction: it summarizes older turns into a shorter form to keep working. Compaction preserves names, file paths, and the essential thread — but it is lossy. Nuance gets flattened.

CONTEXTlifecycle
  • 0–50% · safe to work
  • 50–80% · active zone
  • 80–95% · HANDOFF NOW
  • 95–100% · compaction risk

This is why Tab 4's handoff protocol matters so much: when you're above 80%, don't wait for compaction to rescue you. Write out the session state yourself, relaunch fresh, and keep all the nuance.

Reasoning level

Some Claude models expose a knob for how long to think before answering. The claw alias sets --effort max, which on Opus 4.7 means adaptive thinking is allowed to run as long as the task deserves. On Sonnet 4.6 and Haiku 4.5, extended thinking is a separate explicit mode you enable per-call. For agency work, the default guidance is simple: Opus 4.7 at max effort, always. Cheaper models are a future optimization, not a starting point.

What git is

Git records a timeline of snapshots of your project. A commit is one snapshot. A branch is a moving pointer to the latest commit on a line of work. GitHub is a website that hosts your git history so other machines (and Vercel) can pull it. Those four sentences get you through 90% of agency work.

branches, commits, and a mergemainc1c2c3c4feature/onboardingf1f2f3merge

The commands that do the work

zsh — the git loop
projectgit status
On branch main · 3 files changed
projectgit add .
projectgit commit -m "Add lead-intake form"
projectgit push
  • git status — what changed since the last commit.
  • git add <paths> — stage specific files for the next commit. git add .stages everything (convenient but careful; it's how .env files accidentally get committed).
  • git commit -m "message" — snapshot staged changes with a message.
  • git push — send local commits up to GitHub.
  • git pull— pull down whatever's new on the remote.

Branching for parallel work

When you're trying something that might not work, create a branch: git checkout -b feature/onboarding-flow. Make your commits there. If it works, merge to main. If it doesn't, delete the branch and nothing on main was touched. Branches are cheap; use them.

The .gitignore file

A text file at the repo root listing patterns git should never track. .env* is always there. node_modules/ is always there. If you catch yourself about to commit a service account JSON, check that .gitignore excludes it before you run git add.

What a deployment is

A deployment is the act of copying your code from your laptop (or GitHub) to a server that the internet can reach, and configuring a domain so users land on it. On Vercel, that's literally one command — everything hard about hosting is abstracted away.

Local vs production

Local

localhost:3000

npm run dev starts a dev server only you can reach. Hot reload on every save. No SSL, no real domain, not shared with anyone. This is where you build.

Production

claude-agency-playbook.vercel.app

vercel --prod --yes builds an optimized bundle, uploads it, gives you a live URL with HTTPS, and makes it reachable from any device in seconds.

The deploy flow

bashTerminal · deploy
cd ~/Documents/client-a
vercel --prod --yes
# Inspect:  https://vercel.com/your-team/client-a/abc123
# Production: https://client-a.vercel.app [4s]

Custom domains

The .vercel.app URL is fine for internal tools; client-facing work usually gets a real domain. The two-minute version: add a CNAME record at your DNS host pointing your subdomain (e.g. ai.onlineakademija.com) at cname.vercel-dns.com, then add the domain in the Vercel dashboard. Vercel polls DNS, provisions an SSL certificate, and flips the domain live — usually in under five minutes.

For apex domains (example.comwith no subdomain) you set an A record to Vercel's IP instead. See docsVercel · Add a domain for the current exact values — they occasionally change and the docs are authoritative.

Environment variables in production

Your .env.local only exists on your laptop. To give the production deployment access to ANTHROPIC_API_KEY, add it in the Vercel dashboard (or vercel env add ANTHROPIC_API_KEY production). The next deploy picks it up. Never commit .env files to git — see the previous section.