The story behind HTTP 200 "OK"

What's in an HTTP response? I've been writing software for the web since the early 2000s and have incrementally learned things about HTTP. There are status codes, like "200" and "404". There are headers, for Content-Type and headers to control cache settings. There are different versions of HTTP itself, like 1.1, 2, and 3. HTTP requests and responses can contain data, in the message body.


But there's one thing I didn't notice until yesterday. A quirk that was included in the HTTP 1.1 specification with an authors note that it's mostly there for historical reasons: the reason-phrase.

None of this information is useful. The reason-phrase is barely supported on the web and was always an oddity, but keep reading if you like oddities!

If you're used to JavaScript’s fetch() method to make HTTP requests, you've seen the reason-phrase under a different name: statusText:

Create val(await fetch('')).statusText

What is statusText? I had assumed that it was something that JavaScript itself provides, by looking up the status code 200 and matching it with the text "OK". I was wrong!

When I look at a raw HTTP response, I see the first few lines are like this:

HTTP/1.1 200 OK
Date: Thu, 17 Aug 2023 15:16:42 GMT
Content-Type: text/plain;charset=UTF-8

The reason phrase

So what is that text? I dug around in the HTTP 1.0 specification and found the section Status Code and Reason Phrase.

The Status-Code element is a 3-digit integer result code of the attempt to understand and satisfy the request. The Reason-Phrase is intended to give a short textual description of the Status-Code. The Status-Code is intended for use by automata and the Reason-Phrase is intended for the human user. The client is not required to examine or display the Reason-Phrase.

That also lists recommended reason phrases, like OK for 200 and Not Found for 404. And notes that you can choose different phrases without affecting the protocol.

The HTTP 1.1 specification adds a little color about the reason-phrase:


So, with a HTTP server, you can customize your reason phrase! Here's an example with a val on Val Town:

Create vallet customReason = (req) => new Response("", { statusText: 'Hello world!', });

Unfortunately, this doesn't work! The response that Val Town produces is reorganized and optimized by Cloudflare, which upgrades requests and responses from HTTP 1.1 to HTTP 2. And sadly, HTTP 2 dropped support for the custom reason-phrase.

RIP the reason-phrase. It was present even in a 1992 draft of the HTTP specification, and was a weird and under-appreciated way to pilfer extra information in a response. Now, thanks to HTTP/2 and the commonplace use of proxies and CDNs like Cloudflare, it's no longer usable. It was fun while it lasted.

export let reasonPhrase = () => {
return new Response("Hello world", {
status: 200,
statusText: "This can be customized!",
👆 This is a val. Vals are TypeScript snippets of code, written in the browser and run on our servers. Create scheduled functions, email yourself, and persist small pieces of data — all from the browser.