hectoday
DocsCoursesChangelog GitHub
DocsCoursesChangelog GitHub

Access Required

Enter your access code to view courses.

Invalid code

← All courses HTTP from scratch

What is HTTP

  • The request-response model
  • Anatomy of an HTTP request
  • Anatomy of an HTTP response

Methods

  • GET and HEAD
  • POST
  • PUT, PATCH, and DELETE
  • OPTIONS and CORS preflight

Status codes

  • 2xx success
  • 3xx redirection
  • 4xx client errors
  • 5xx server errors

Headers

  • Request headers
  • Response headers
  • Custom headers

The body

  • JSON
  • Form data and multipart
  • No body

Connections

  • TCP, DNS, and TLS
  • HTTP/1.1 vs HTTP/2
  • Cookies and state

Putting it all together

  • Building a server from scratch
  • From scratch to framework

Request headers

The invisible instructions

We have seen headers in almost every lesson so far. They showed up in requests, in responses, and we quickly explained what a few of them do. But headers are doing a lot more work than we have given them credit for. They carry the instructions that make HTTP actually work: who is making the request, what format they want, what credentials they have, what browser they are using. This lesson goes deeper into the headers the client sends.

Content-Type

This one comes first because getting it wrong causes the most confusion. Content-Type tells the server the format of the request body. It is only needed on requests that have a body (POST, PUT, PATCH).

Content-Type: application/json            -> JSON body
Content-Type: application/x-www-form-urlencoded  -> Form data
Content-Type: multipart/form-data         -> File uploads
Content-Type: text/plain                  -> Plain text

What happens if you send a JSON body without Content-Type? The server receives a bunch of raw bytes and has no idea what they mean. It might try to parse them as form data and get garbage. It might reject the request entirely. Always set Content-Type when you are sending a body.

Accept

Accept is the opposite of Content-Type. Instead of telling the server what you are sending, it tells the server what you want back.

Accept: application/json      -> "Send me JSON"
Accept: text/html             -> "Send me HTML"
Accept: */*                   -> "Send me anything"

If the server cannot produce the format you asked for, it could return 406 Not Acceptable. But in practice, most JSON APIs ignore the Accept header and always return JSON.

Authorization

This is how the client sends credentials. The format depends on the authentication scheme:

Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...    -> JWT token
Authorization: Basic dXNlcjpwYXNz                -> Base64(username:password)

Bearer tokens are the most common in modern APIs. The token was issued during login, and now the client includes it on every request to prove who they are.

[!NOTE] The Authentication course covers Bearer tokens (JWTs) and session-based auth in full. This lesson explains the HTTP mechanism: the Authorization header is how credentials travel from client to server.

Cookie

Cookies are key-value pairs that the server previously stored on the client. The browser sends them back automatically on every request to the same domain.

Cookie: session=abc123; theme=dark

Multiple cookies are separated by ;. The server set these cookies earlier using Set-Cookie (which we will cover in the next lesson). The browser handles all of this automatically.

User-Agent

User-Agent identifies the client making the request.

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
User-Agent: curl/7.88.1
User-Agent: my-api-client/1.0

Browsers send long, detailed strings. curl sends its version number. Your application can send whatever it wants. Servers use User-Agent for analytics, compatibility decisions, and bot detection.

Host

Host tells the server which website the request is for. A single IP address can host multiple websites, so this header resolves the ambiguity. It is required in HTTP/1.1.

Host: api.example.com
Host: api.example.com:8080   -> includes port if non-standard

Other headers worth knowing

If-None-Match sends a cached ETag for conditional requests (from the Caching course). The server checks if the data has changed.

If-Modified-Since sends a timestamp for conditional requests.

Origin tells the server which site initiated the request. This is used for CORS, which we covered in the OPTIONS lesson.

Referer is the page that linked to this request. (Yes, “Referer” is misspelled. It has been misspelled since 1996, and it is too late to fix it.)

Those are the key request headers. The next lesson covers the other side: the headers the server sends back.

Exercises

Exercise 1: Use curl -H "Accept: application/json" to request JSON. Then change it to Accept: text/html. Compare the responses.

Exercise 2: Use curl -H "Authorization: Bearer tok_123" to send a token. On the server side, read the header and log it.

Exercise 3: Use curl -v and find the User-Agent header in the request. Then override it with -H "User-Agent: my-app/1.0".

Why must a POST request include a Content-Type header?

← 5xx server errors Response headers →

© 2026 hectoday. All rights reserved.