EN
Dashboard
Local Time Zone
Account
My News
Identity Authentication
Whether you're a developer interacting with APIs, a QA engineer testing web services, or a sysadmin automating scripts, cURL is an indispensable Swiss Army knife in your toolkit. This powerful command-line tool is capable of transferring data from or to a server. However, to truly unlock the full potential of cURL, you must master the art of manipulating HTTP headers. cURL headers are the core components of an HTTP request that pass crucial metadata to the server about the request itself, the client, and the type of response it expects.
Properly setting cURL headers allows you to mimic different browsers, authenticate yourself, request specific data formats like JSON or XML, and even influence server caching behavior. Many advanced web interactions depend on custom HTTP headers, and without knowing how to send them, your tasks can come to a standstill.
This guide is designed to be your definitive resource for learning how to send HTTP headers with cURL. We'll start with the basics and move progressively into advanced use cases, covering everything from viewing default headers to sending multiple custom ones. By the end of this article, you will be able to confidently construct any HTTP request you need, enabling more precise and effective communication with web services.
The key to sending HTTP headers with cURL is the -H or --header flag. This flag allows you to define an HTTP header directly on the command line to be included in the request. The basic syntax is simple and intuitive:
downloadcontent_copyexpand_less
curl -H "Header-Name: Header-Value" https://example.com
Here:
-H "...": Tells cURL you are defining a header.
Header-Name: The name of the HTTP header you want to send (e.g., Content-Type).
Header-Value: The value you are setting for that header (e.g., application/json).
https://example.com: The destination URL.
This simple command is the foundation for everything you need to know about manipulating cURL headers. The following sections will build upon this to demonstrate its powerful flexibility.
Before you manually add anything, cURL is smart enough to send a few default HTTP headers automatically to ensure the request can be properly handled by most web servers. To see these default cURL headers, you can use the -v or --verbose flag, which prints out detailed connection information, including the outgoing request headers.
Let's look at a simple GET request:
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
curl -v https://example.com
In the output, you will see lines prefixed with >, which represent data sent from your client (cURL) to the server. You will typically see default headers like these:
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
> GET / HTTP/1.1> Host: example.com> User-Agent: curl/7.64.1> Accept: */*
>
Host: This is a required header that specifies the domain name of the server you are requesting.
User-Agent: Identifies the client making the request. By default, it announces itself as curl and its version.
Accept: This header tells the server that the client can accept any type of response (*/* means "any type").
If you send a POST request with data (e.g., using the -d flag), cURL will also automatically add two more default headers:
Content-Length: Tells the server how large the data you're sending is.
Content-Type: Defaults to application/x-www-form-urlencoded.
Understanding these defaults is important because, in many cases, you will need to override them to meet the requirements of a specific API or web application.
Now that we know cURL sends default headers, how do you change them? It's incredibly simple: just use the -H flag and provide the name of the header you want to change with its new value. cURL will automatically replace the default value with the one you provided.
The most common example is changing the User-Agent. Many web services serve different content based on the User-Agent, and mimicking a real browser is a common practice in web scraping or testing.
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" https://example.com
With this command, cURL will no longer send User-Agent: curl/7.64.1. Instead, it will send the User-Agent string you specified, which appears as a Chrome browser. This ability to override default cURL headers is the first step toward advanced web interactions.
Beyond changing defaults, the most powerful function of the -H flag is to send custom cURL headers that cURL does not send by default. This is essential for interacting with modern APIs.
Many APIs use a Bearer Token scheme for authentication. The client must provide a valid token in the Authorization header.
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
curl -H "Authorization: Bearer YourApiTokenGoesHere" https://api.example.com/v1/data
Without this custom header, the API server would likely return a 401 Unauthorized error.
When you POST JSON data to an API, you must explicitly tell the server that the format of your data is application/json. While cURL sends a default Content-Type when you use -d, its default value is designed for form data. You need to override it manually.
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
curl -X POST -H "Content-Type: application/json" -d '{"name":"John Doe","email":"[email protected]"}' https://api.example.com/v1/users
In this example, we sent a custom HTTP header with cURL (Content-Type) to ensure the API can correctly parse the JSON payload we're sending.
In practical applications, you will often need to send multiple custom or overridden headers at once. For example, you might need to provide an Authorization token and a Content-Type at the same time.
To send multiple cURL headers, you simply use the -H flag multiple times.
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
curl -X POST \
-H "Authorization: Bearer YourApiTokenGoesHere" \
-H "Content-Type: application/json" \
-d '{"key":"value"}' \
https://api.example.com/v1/resource
cURL will include each -H flag you provide as a separate HTTP header in the outgoing request. You can add as many headers as you need, which makes cURL flexible enough to build any complex HTTP request.
This is a more advanced technique. Sometimes, you may not want to change a default header but remove it entirely. For instance, certain specific testing scenarios might require a request to not include the Accept header.
You can achieve this by providing an empty value, which is done by following the header name with a semicolon ;
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
curl -v -H "Accept;" https://example.com
When you run this and view the verbose output, you will notice that the Accept: */* line is no longer present in the outgoing request. This is very useful for scenarios where you need to craft a request with surgical precision for debugging or testing.
So far, we have focused on how to send cURL headers. But it is just as important to be able to see the response headers that the server sends back. Response headers contain vital information about the response, such as the content type, server software, caching policies, and cookies.
cURL provides two main flags for viewing response headers:
-i or --include: This flag will include the HTTP response headers in the output along with the response body. This is great for seeing the full response.
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
curl -i https://example.com
The output will first show the HTTP status line (e.g., HTTP/1.1 200 OK), followed by all the response headers, a blank line, and finally the HTML content of the page.
-I or --head: This flag tells cURL to fetch and show the HTTP response headers only. It accomplishes this by sending a HEAD request instead of a GET request, which is more efficient as the server does not return the response body.
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
curl -I https://example.com
The output will consist only of the status line and the response headers, perfect for quickly checking a server's status or debugging a redirect.
Once you have mastered manipulating cURL headers, you can apply this skill to a wide variety of real-world scenarios:
API Testing: Sending Authorization for authentication, Content-Type to specify data format, and other custom headers required by the API (e.g., X-Api-Key).
Web Content Scraping: Setting a realistic User-Agent to mimic a browser, sending Accept-Language to request content in a specific language, or providing a Referer header to simulate navigation from another page.
Content Negotiation: Using the Accept header (e.g., Accept: application/json) to explicitly tell a server what data format you wish to receive.
Web Cache Testing: Sending Cache-Control: no-cache to request the freshest version of a resource, or sending an If-None-Match header to check if a resource has been updated.
Session and State Management: Using the Cookie header to send back cookies previously set by the server to maintain a logged-in state or a user session.
HTTP headers are the unsung heroes of web communication, and cURL gives you a powerful and flexible toolkit to command them with precision. Through the simple yet mighty -H flag, you can override defaults, add custom metadata, and even remove certain cURL headers entirely. Whether you need to simulate a specific browser, interact with a protected API, or debug a complex web issue, mastering how to send HTTP headers with cURL is an essential skill.
We've covered everything from the basic syntax to advanced techniques and practical use cases. You should now be well-equipped to start using cURL headers confidently in your own projects. The next time you need to craft an HTTP interaction that goes beyond a simple GET request, remember the -H flag—it will be your key to success.
A: No, there is absolutely no difference. They are two forms of the same flag. -H is the short form, while --header is the more descriptive long form. They are functionally identical, and you can use whichever you prefer. In scripts, -H is often used for brevity.
A: No. Each -H or --header flag can only define one HTTP header. If you need to send multiple headers, you must use the -H flag multiple times, for example: curl -H "Header1: Value1" -H "Header2: Value2" ....
A: As seen in the User-Agent example, you need to wrap the entire header (both name and value) in double quotes ". For instance: curl -H "X-Custom-Header: This value has spaces" https://example.com.
A: Not by default. While a server can send cookies via the Set-Cookie response header, cURL will not automatically send them back on subsequent requests. To manage cookies, you need to use the -c (--cookie-jar) flag to save received cookies to a file and the -b (--cookie) flag to read and send cookies from that file. For example: curl -c cookies.txt https://example.com/login followed by curl -b cookies.txt https://example.com/dashboard.
A: According to the HTTP/1.1 specification, the order of headers generally does not matter, with a few exceptions (the Host header is typically first). However, in 99.9% of practical applications, you do not need to worry about the order in which you list your -H flags on the command line. cURL and the server will handle them correctly.
A: If you have a large number of headers or want to keep them separate from your script, you can save them in a file, one header per line. You can then simply loop through the file in your cURL command. A simple bash example would be:
downloadcontent_copyexpand_less
IGNORE_WHEN_COPYING_START
IGNORE_WHEN_COPYING_END
headers_file="headers.txt"
curl_opts=""while IFS= read -r line; do
curl_opts+=" -H \"$line\""done < "$headers_file"
# Execute the cURL command dynamicallyeval "curl $curl_opts https://example.com"
```This approach offers great flexibility for managing complex **cURL headers**.