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
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.
echo $PATH
# /opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbinEnvironment 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 vendor│Anthropic, 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
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.
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.
Claude Haiku 4.5
Smallest current model. Fast and cheap. Useful for classification, routing, and simple extraction at scale.
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 anthropic│Claude 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
Terminal (this course's default)
claw alias. Full filesystem access, full shell access, long sessions.Cursor integration
claude.ai/code
Desktop / mobile apps
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
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
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.
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.
Anatomy of a request
- URL — the endpoint. Example:
https://api.fathom.ai/external/v1/meetings. - Method —
GETto read,POSTto create,PATCHto update,DELETEto remove. Servers use this to route. - Headers — metadata. Most importantly
Authorization(your key) andContent-Type(usuallyapplication/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
curl -i https://httpbin.org/get
# HTTP/2 200
# content-type: application/json
# { "args": {}, "headers": {...}, "url": "https://httpbin.org/get" }No auth needed — sandbox│httpbin.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.
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.
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.
- 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.
The commands that do the work
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.envfiles 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
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.
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
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 docs│Vercel · 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.