Often while using `curl` with URLs that return a JSON response, I need to print the HTTP response headers along with the JSON response. Here is an example that shows how this can be done:

    $ curl -sSi https://susam.net/code/lab/json/books.json
    HTTP/1.1 200 OK
    Server: nginx/1.18.0
    Date: Sat, 05 Apr 2024 11:53:24 GMT
    Content-Type: application/json
    Content-Length: 172
    Last-Modified: Sat, 05 Apr 2024 11:53:05 GMT
    Connection: keep-alive
    ETag: "67f119a1-ac"
    Accept-Ranges: bytes

    [
      {"title": "Gulliver's Travels", "author": "Jonathan Swift", "published": 1726},
      {"title": "Treasure Island", "author": "Robert Louis Stevenson", "published": 1883}
    ]

The above output is obtained using curl 7.77.0 (x86_64-apple-darwin21.0). The `-i` option is responsible for including the HTTP response headers. The `-s` and `-S` options are not too important for the current discussion but I usually happen to use them out of habit. The `-s` option suppresses the progress meter and error messages but the `-S` re-enables the display of error messages. This helps me avoid the progress meter in the output without having to lose visibility of any errors that may arise.

So far so good! But can we also have the JSON response pretty-printed with say `jq`? The above command prints both the HTTP headers and the response to the standard output, so piping the standard output to `jq` does not work. The `jq` command fails with an error as soon as it encounters the HTTP headers.

If, however, we manage to send the HTTP header and the response to different streams or files, then we could utilise `jq` to pretty-print the stream or file that contains the JSON response. Here is an example that shows how to do this:

    $ curl -sSD head.txt -o out.json https://susam.net/code/lab/json/books.json && cat head.txt && jq . out.json
    HTTP/1.1 200 OK
    Server: nginx/1.18.0
    Date: Sat, 05 Apr 2024 11:53:51 GMT
    Content-Type: application/json
    Content-Length: 172
    Last-Modified: Sat, 05 Apr 2024 11:53:05 GMT
    Connection: keep-alive
    ETag: "67f119a1-ac"
    Accept-Ranges: bytes

    [
      {
        "title": "Gulliver's Travels",
        "author": "Jonathan Swift",
        "published": 1726
      },
      {
        "title": "Treasure Island",
        "author": "Robert Louis Stevenson",
        "published": 1883
      }
    ]

Alternatively, we can achieve this using a single command by printing the the HTTP headers to standard error. This ensures that only the JSON response is printed to standard output, which we can then pretty-print using `jq`. Here is an example:

    $ curl -sSD /dev/stderr https://susam.net/code/lab/json/books.json | jq .
    HTTP/1.1 200 OK
    Server: nginx/1.18.0
    Date: Sat, 05 Apr 2024 11:54:12 GMT
    Content-Type: application/json
    Content-Length: 172
    Last-Modified: Sat, 05 Apr 2024 11:53:05 GMT
    Connection: keep-alive
    ETag: "67f119a1-ac"
    Accept-Ranges: bytes

    [
      {
        "title": "Gulliver's Travels",
        "author": "Jonathan Swift",
        "published": 1726
      },
      {
        "title": "Treasure Island",
        "author": "Robert Louis Stevenson",
        "published": 1883
      }
    ]