P.4 · How the Web Works

P.4 · 40 min

How the Web Works

Here is a secret about your resume: if you have ever wired a Zapier webhook into GoHighLevel, you have been doing HTTP integrations for years. You configured a URL, chose POST, watched JSON arrive, and debugged the run when it failed. What you were missing is the model underneath, which is why every failure felt like weather instead of mechanics. This lesson installs the model. Nothing in it will be brand new; all of it will be newly legible.

The map

The web runs on one loop: a client sends a request to a server, the server sends back a response, done. No open line, no ongoing conversation. Every page load, API call, and webhook delivery is this loop, repeated.

A URL is the address of the request: https://api.github.com/repos/vercel/ms breaks into a scheme (https, encrypted HTTP), a host (api.github.com), and a path (/repos/vercel/ms, which resource on that host). DNS, in one paragraph: computers route by IP address, not names, so before anything else the client asks the DNS system "what address is api.github.com?" and gets back something like 140.82.112.6. That lookup is the phonebook of the internet, it is why domains cost money, and it is the last time we will mention it.

The request carries a verb saying what you want done:

  • GET reads a resource, changes nothing
  • POST creates something (or generally: submits data)
  • PUT and PATCH update, wholly or partially
  • DELETE does what it says

The response carries a status code, a three-digit summary of how it went. The first digit is the plot: 2xx succeeded, 3xx moved, 4xx you messed up, 5xx the server messed up. The ones you will actually see: 200 fine, 201 created, 301 moved permanently, 400 malformed request, 401 who are you (bad or missing credentials), 403 I know who you are and the answer is no, 404 no such resource, 429 slow down, 500 server exploded, 503 server unavailable. When an integration fails, the status code is the first fact worth knowing, because 4xx means fix your request while 5xx means their problem, wait or escalate. That single distinction resolves half of all integration arguments.

Both requests and responses carry headers, key-value metadata: Content-Type: application/json says what format the body is, Authorization: Bearer YOUR_TOKEN carries credentials. And the body carries the payload, which for APIs is almost always JSON: nested objects in braces, arrays in brackets, strings and numbers at the leaves. You have watched JSON scroll past in Zapier task history; now you know its name and shape.

Rendering diagram...

So what separates a browser from an API client? The browser requests HTML and renders it into pixels; an API client requests JSON and feeds it to code. Same protocol, same verbs, same status codes. A server is just a program that listens for requests and decides what to send back; in Track A you will write one in an afternoon. A webhook is the same loop with the direction flipped: instead of you asking a service for data, the service sends a POST to a URL you registered, the moment something happens. When GHL fires a webhook at Zapier, GHL is the client and Zapier is the server. You have been hosting HTTP endpoints without being told.

Tutor first

PromptWeb mechanics tutor

You are my tutor on HTTP and web mechanics. I already use webhooks and Zapier operationally, so build on that. Quiz me one scenario at a time: give me a realistic integration situation (a webhook failing, an API returning a status code, a JSON body to read) and ask me to diagnose or predict. Escalate difficulty. When I am wrong, do not lecture: ask the question that exposes the wrong assumption. After 8 questions, list the concepts I should drill.

The lab: speak HTTP by hand

curl is a terminal tool that makes HTTP requests and shows you exactly what came back, no rendering, no magic. It ships with macOS and most Linux distributions. You will use it constantly in this course to check what an API really said, as opposed to what your code thinks it said.

Lablab-p-4curl a real API

Goal: Make live HTTP requests to GitHub's public API, read the JSON, and deliberately cause a 404 and a 401.

  1. Make a real request to a real server:
curl https://api.github.com/repos/vercel/ms

Check: a wall of JSON. In it, find "full_name": "vercel/ms", "stargazers_count" with a number, and "description". You just did, by hand, what every Zapier action does under the hood.

  1. See the whole conversation, not just the body. The -i flag includes response headers:
curl -i https://api.github.com/repos/vercel/ms

Check: the first line reads HTTP/2 200. Below it, headers: find content-type: application/json and (on GitHub specifically) x-ratelimit-remaining, which counts down how many unauthenticated requests you have left this hour. Headers are where APIs put operational truth.

  1. Cause a 404, on purpose:
curl -i https://api.github.com/repos/vercel/this-repo-does-not-exist-xyz

Check: first line HTTP/2 404, and a small JSON body with "message": "Not Found". Diagnosis when you see this in the wild: the URL or resource is wrong. Not your key, not their outage. The path.

  1. Cause a 401, on purpose. Send credentials that are garbage:
curl -i -H "Authorization: Bearer not-a-real-token" https://api.github.com/user

Check: HTTP/2 401 with "message": "Bad credentials". The -H flag added a header, exactly the header every authenticated integration you have ever configured sends silently. When a working integration starts throwing 401s, someone rotated or revoked a key. You now know that from the code alone.

  1. Read JSON like a path. Ask for one field from the response. If you are on macOS or have python3 anywhere:
curl -s https://api.github.com/repos/vercel/ms | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['full_name'], d['stargazers_count'])"

Check: prints vercel/ms and a number. The point is not the python: it is that d['full_name'] is a path into the JSON tree, the same dot-path thinking Zapier uses when you map contact.email into an action. Nested data, addressed by keys.

Verify

  • You got a 200, a 404, and a 401, and can state without looking what each one means and whose fault it is.
  • You can point at the three parts of https://api.github.com/repos/vercel/ms and name them.
  • Given the JSON body from step 1, you can say where owner.login lives (inside the owner object, at the top level of the response).
>Troubleshooting
  • curl: command not found (mostly Windows without WSL). Do this lab inside WSL, where curl is standard. On Linux: sudo apt install curl.
  • Step 1 returns a 403 with a message about rate limits. Unauthenticated clients get a limited number of requests per hour from GitHub, and a shared office network can exhaust it. Wait an hour or try from another network; the limit itself is a lesson in how public APIs defend themselves.
  • The JSON is an unreadable wall. That is normal. Pipe through python3 -m json.tool to pretty-print it. Wall-of-JSON to pretty-printed tree is a one-pipe fix, and now you know a second pipeline.

Where it breaks

The model breaks people in three places. First, treating status codes as decoration. An integration "randomly fails," and the run logs have been saying 429 for a week: the API was asking them to slow down, in writing, and nobody read it. Second, assuming the request arrived because it was sent. Between you and the server sit DNS, TLS, proxies, and the network itself; when something fails silently, curl the endpoint by hand and see which layer answers. Third, confusing authentication failures with outages. A 401 at 9am Monday is a rotated key, not a down server, and now you will never burn an hour on that again.

Weather-based debugging

"The webhook is being flaky again. Re-running the Zap a few times usually fixes it. If not I will wait and see if it clears up this afternoon."

Model-based debugging

"The run log shows the POST got a 401 starting Monday 9:02am. Nothing 5xx, so their service is up. Somebody rotated the API key Friday. Re-issue the key, update the header, re-run the failed jobs."

Knowledge check

Knowledge check

Q1A webhook integration that ran fine for months starts returning 401 on every delivery as of this morning. Most likely cause?
Q2Your code calls an API and gets a 500. What does that tell you, and what is the right first move?
Q3An API response is {"contact": {"id": 88, "tags": ["vip", "hot"]}}. Which statement is accurate?
Q4Why can curl-ing an endpoint by hand be more informative than reading your application's error log for the same failure?

Sources

  • GitHub REST API, called live during authoring; the lab's 200, 404, and 401 responses were all reproduced as described: https://api.github.com (fetched July 2026)

HTTP's verbs, status codes, and header mechanics are decades-stable; the lesson's only volatile dependency is the GitHub API being publicly reachable, verified above.