Skip to content

Query Params and Headers

The URL path names the resource. Query params narrow it down; headers carry metadata about the request itself.

Query params: questions about the collection

/items?color=red&sort=price&limit=10

After the ?: key=value pairs joined by &. They're for filtering, sorting, and paging — never for the resource's identity (that's the path's job):

/items/42          → the item (path)
/items?color=red   → items, but only red ones (query)
curl "http://127.0.0.1:8471/items?limit=1"

Quote the URL — the shell treats & as "run in background" and ? as a wildcard. Unquoted, your query silently becomes two commands. Single or double quotes both work; pick one and be consistent.

Special characters get percent-encoded: a space becomes %20, & inside a value becomes %26. Most HTTP libraries (Python's requests, curl's --data-urlencode) do this for you — hand-rolled URLs with raw spaces are a classic 400.

Headers you send

Header Purpose Example
Authorization Who you are Bearer abc123
Content-Type What your body is application/json
Accept What you want back application/json
User-Agent Which client you are (curl sends its own)
curl -H "Authorization: Bearer secret123" http://127.0.0.1:8471/secret

Check (verified):

{"msg": "ok"}
HTTP 200

And without the header:

curl -s -w "\nHTTP %{http_code}\n" http://127.0.0.1:8471/secret

Check (verified):

{"error": "unauthorized"}
HTTP 401

Same URL, different header, different universe. Headers are invisible in the browser address bar, which is why API debugging lives in curl and devtools, not in pasting URLs.

Headers you receive

curl -v http://127.0.0.1:8471/items 2>&1 | grep -E "^[<>]"

Check (verified shape):

> GET /items HTTP/1.1
> Host: 127.0.0.1:8471
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.0 200 OK
< Content-Type: application/json

> lines are what you sent; < lines are what came back. This is the single most illuminating view in API work: the actual request, not what you thought you sent.

Next: Authentication