HEAD requests are useful when response metadata matters more than the payload itself. In cURL, a header-only probe makes it possible to confirm that an endpoint still answers, inspect caching or content details, and check redirect or TLS behavior without downloading the full document or API body.

The --head option, or short -I form, tells cURL to perform an HTTP HEAD transfer so the server returns the status line and headers that would normally accompany a GET response. This is practical for uptime checks, redirect tracing, certificate-related checks, and quick validation before larger transfers.

Not every application implements HEAD consistently. Some endpoints return 405 Method Not Allowed, some omit headers that appear on GET, and some proxy or CDN layers rewrite header sets along the way. Use --location when redirect hops matter, keep credential-bearing headers scoped carefully, and prefer --head over -X HEAD so cURL stays in header-only mode.

Steps to send HEAD requests with cURL:

  1. Send a basic header-only request to confirm status and response metadata without downloading the body.
    $ curl --silent --show-error --head 'https://status.example.net/v1/health'
    HTTP/2 200
    content-type: application/json; charset=utf-8
    content-length: 428
    server: envoy
    cache-control: no-store
    strict-transport-security: max-age=31536000

    Use --head or -I when a lightweight status-and-header check is enough and the endpoint supports HEAD correctly.

  2. Follow redirects with the same HEAD request when the first URL is only a front door to the final resource.
    $ curl --silent --show-error --head --location 'https://edge.example.net/releases/current'
    HTTP/2 302
    content-length: 0
    server: envoy
    location: /releases/agent/linux-amd64/current
    cache-control: no-store
    ##### snipped #####
    HTTP/2 200
    content-type: application/gzip
    content-length: 18432076
    server: envoy
    accept-ranges: bytes

    --location replays the HEAD request at each Location target so every hop and the final response remain visible.

  3. Verify that cURL actually sent HEAD on the wire before turning the command into a reusable check.
    $ curl --silent --show-error --head --verbose 'https://status.example.net/v1/health' 2>&1 | grep -E '^(> HEAD|> Host:|< HTTP/|< content-type:)'
    > HEAD /v1/health HTTP/2
    > Host: status.example.net
    < HTTP/2 200
    < content-type: application/json; charset=utf-8

    Use --head or -I instead of -X HEAD. Forcing the method with --request changes the verb text only and can leave cURL expecting a body that never arrives.

  4. Print script-friendly transfer metrics when a monitoring job needs a clear success signal instead of raw headers alone.
    $ curl --silent --show-error --head --output /dev/null \
      --write-out 'status=%{response_code}\nbody=%{size_download}\nheaders=%{size_header}\n' \
      'https://status.example.net/v1/health'
    status=200
    body=0
    headers=214

    A body value of 0 confirms that no payload bytes were transferred, while headers gives a compact size check for alerting or regression scripts.

  5. Check whether a target actually supports HEAD before using it in scheduled probes, and fall back to GET only when the endpoint explicitly refuses HEAD.
    $ curl --silent --show-error --head https://api.example.net/v1/export/jobs/8421
    HTTP/1.1 405 Method Not Allowed
    Allow: GET, OPTIONS
    Content-Length: 0
    
    $ curl --silent --show-error https://api.example.net/v1/export/jobs/8421
    {"job_id":"job_8421","state":"ready","download_count":1}

    A 405 response with an Allow header means the endpoint rejected HEAD itself, not that cURL was used incorrectly. Keep the fallback explicit so monitoring does not silently change request semantics.