---
name: "CURLOPT_HTTPSIG_HEADERS"
section: "3"
platform: "linux"
package: "curl"
version: "8.23.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/CURLOPT_HTTPSIG_HEADERS"
---

# CURLOPT\_HTTPSIG\_HEADERS(3)

components to sign for HTTP Message Signatures

## NAME

CURLOPT\_HTTPSIG\_HEADERS - components to sign for HTTP Message Signatures

## SYNOPSIS

```
#include <curl/curl.h>
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HTTPSIG_HEADERS,
                          char *components);
```

## DESCRIPTION

This feature is **experimental** and may change before it is considered stable. We advise against using it in production.

Pass a space-separated list of component identifiers to include in the RFC 9421 HTTP Message Signature.

Derived components are given as bare names:

\- **method** - the HTTP method (GET, POST, etc.) - **authority** - the host and optional port - **path** - the request path - **query** - the query string including the leading *?*

HTTP header fields are given with a trailing colon, for example *content-type:* or *content-digest:*. This mirrors how a header looks and keeps a leading *@* free for its usual curl meaning (read the value from a file).

If this option is not set, the default components are **method**, **authority**, **path** (plus **query** when a query string is present).

- Signing request headers

  Header components are resolved from the list set with *[CURLOPT\_HTTPHEADER(3)](/CURLOPT_HTTPHEADER/3.md)* only. Headers that libcurl adds later (such as the default *User-Agent*) are **not** visible to the signer unless the application supplies them explicitly.

  To sign *User-Agent*, supply it via *[CURLOPT\_HTTPHEADER(3)](/CURLOPT_HTTPHEADER/3.md)* together with this option before the transfer; see EXAMPLE.

  Each component identifier may appear at most once (RFC 9421 Section 2). Listing the same component twice returns *CURLE\_BAD\_FUNCTION\_ARGUMENT*.

  At most 16 components are accepted; supplying more returns *CURLE\_BAD\_FUNCTION\_ARGUMENT*.

  The application does not have to keep the string around after setting this option.

## DEFAULT

NULL (uses the default component set)

## PROTOCOLS

This functionality affects http only

## EXAMPLE

```
int main(void)
{
  CURL *curl = curl_easy_init();
  struct curl_slist *headers = NULL;
  if(curl) {
    headers = curl_slist_append(headers, "User-Agent: MyApp/1.0");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/api");
    curl_easy_setopt(curl, CURLOPT_HTTPSIG_ALGORITHM, CURLHTTPSIG_ED25519);
    curl_easy_setopt(curl, CURLOPT_HTTPSIG_KEY,
                     "9f8362f87a484a954e6e740c5b4c0e84"
                     "229139a20aa8ab56ff66586f6a7d29c5");
    curl_easy_setopt(curl, CURLOPT_HTTPSIG_KEYID, "my-key-id");
    curl_easy_setopt(curl, CURLOPT_HTTPSIG_HEADERS,
                     "method authority path content-type: user-agent:");
    curl_easy_perform(curl);
    curl_slist_free_all(headers);
  }
}
```

## AVAILABILITY

Added in curl 8.22.0

## RETURN VALUE

*[curl\_easy\_setopt(3)](/curl_easy_setopt/3.md)* returns a CURLcode indicating success or error.

CURLE\_OK (0) means everything was OK, non-zero means an error occurred, see *[libcurl-errors(3)](/libcurl-errors/3.md)*.

## SEE ALSO

[**CURLOPT\_HTTPSIG\_ALGORITHM**(3)](/CURLOPT_HTTPSIG_ALGORITHM/3.md), [**CURLOPT\_HTTPSIG\_KEY**(3)](/CURLOPT_HTTPSIG_KEY/3.md), [**CURLOPT\_HTTPSIG\_KEYID**(3)](/CURLOPT_HTTPSIG_KEYID/3.md)
