Back to blog

cURL POST Request: Extensive Developer Guide 🤖

In web development, skillfully handling HTTP requests¹ is key for interacting with APIs, testing endpoints, and automating web processes. cURL² shines as a top tool thanks to its adaptability, reliability, and extensive use, making it the go-to solution for HTTP requests. This sturdy command-line utility empowers developers to make requests, process responses, handle redirects, manage cookies and sessions, and tackle tasks from basic to advanced, all through the Terminal.

Martin Ganchev

Apr 24, 2024

15 min read

cURL POST Request

This guide is a third from our cURL series and is crafted for software developers who aim to master the art of using cURL to send POST requests. Whether you're looking to submit form data, interact with RESTful APIs, or streamline data submission processes, getting a handle on composing POST requests with cURL is crucial. We start with the fundamentals, including installing cURL and grasping the structure of a POST request. Moving forward, we'll dive into incorporating data in various formats, setting up basic and custom HTTP headers, managing HTTP redirects, and beyond. By the end of this guide, you'll have a solid foundation for sending cURL POST requests and enhancing your know-how arsenal for a wide array of web development aspects.


To send a cURL HTTP POST request:

  • use -X POST for basic requests;
  • -d or --data for key-value pairs;
  • -H for adding headers like Content-Type
  • -F for multipart/form-data when/if uploading files;
  • Use -o to save responses to a file;
  • -v for verbose output;
  • -L to follow redirects.

How to download and install cURL?

Before getting started, check that your system has cURL installed. It usually comes pre-installed on Unix-based systems like Linux and macOS. For Windows users, you can easily download cURL from its official website or access it through Git BashGit Bash or WSLWSL. Not sure which version to get? The cURL Download Wizard can help guide you to the appropriate package.

How to install cURL on Linux?

Install cURL on any Linux system by simply typing the following command in your Ubuntu Terminal:

sudo apt install curl

The process of installing cURL on Linux may differ a bit from one distribution to another, but it usually involves using the distribution's package manager.

How to install cURL on macOS?

To install cURL on macOS, follow these guidelines. MacOS typically comes with cURL pre-installed, but if you need a different version or to ensure it's installed, here's how to proceed:

1. Verify existing installation

Open Terminal and type curl --version to check if cURL is already installed and to verify its version.

2. Install and use Homebrew

If you prefer to manage packages with Homebrew³ (a popular package manager for macOS) or need to install a newer version of cURL, follow the steps below. If Homebrew isn't already installed, you can install it by running:

/bin/bash -c "$(curl -fsSL"

Then, to install cURL use this:

brew install curl

Homebrew will install the latest version of cURL and will manage its dependencies. If you want to use the Homebrew version of cURL over the system's pre-installed version, you may need to add the Homebrew cURL path (/usr/local/opt/curl/bin/curl) to your shell profile (e.g., .bash_profile, .zshrc).

3. Adjust the PATH

If you've installed cURL’s newest version via Homebrew and want to make it the default, you'll need to adjust your system's PATH. Simply add the following line to your shell profile file (~/.bash_profile for Bash or ~/.zshrc for Zsh):

export PATH="/usr/local/opt/curl/bin:$PATH"

Then, reload your profile with source ~/.bash_profile or source ~/.zshrc, or restart your Terminal.

4. Verify version

To verify that the correct version of cURL is being used in your macOS, reopen Terminal and type:

curl --version

You should see the version of cURL installed via Homebrew or the system version if you skipped the Homebrew installation.

How to install cURL on Windows? 

To install cURL on Windows, you have several options at your disposal (choose one):

1. Via Windows 10 or Later Built-in cURL: Modern Windows 10 and later versions come with cURL pre-installed. You can verify its presence by opening the Command Prompt or PowerShell and typing curl --version. If it's installed, you'll see the version information.

2. Using Chocolatey Package Manager⁴:

  • If you prefer managing your tools through a package manager, and Chocolatey is installed, you can add cURL by running:
choco install curl

3. To install cURL on Windows manually, follow these steps:

  1. Download the latest cURL zip file from the official website.
  2. Extract the zip file's contents to a directory of your choice (e.g., C:\Program Files\cURL).
  3. Add the directory where cURL is located to your system's environment variables Path. This allows you to access the cURL command from any command prompt or terminal.
  4. Right-click on This PC or My Computer and select Properties.
  5. Click on Advanced system settings and then Environment Variables.
  6. Under System Variables, find and select the Path variable, then click Edit.
  7. Add the path to the cURL directory to the list of values, and click 'OK'.

4. To verify cURL installation on Windows, open a new Command Prompt or PowerShell window and type curl --version to ensure cURL is correctly installed and accessible.

What is a POST request in cURL?

A cURL POST request offers a method for communicating with web servers and APIs right from the Command line or within a script, enabling the transmission of data to either create or modify resources. This type of request is structured around several key components:

  • URL. Specifies the endpoint to which the request is sent. This is the target resource or API where the data will be processed, provided directly after the cURL command and options.
  • Headers. Included using the -H or --header flag followed by the header name and value. Headers in a cURL POST request can include content type (e.g., -H "Content-Type: application/json" for JSON payloads), authentication (e.g., -H "Authorization: Bearer TOKEN"), and any other necessary metadata required by the server or API.
  • Body. The data payload of the POST request added using the -d or --data flag. This can be a string of key-value pairs for form data, a JSON string, or even a reference to a file containing the payload (using @filename syntax).

Building a cURL POST request with these components gives developers precise control over the data they send to servers, positioning cURL as an instrument for testing, automation, and engagement with web services.

How to send a basic POST request?

To send a basic POST request with cURL, use the -X POST option followed by the URL you're targeting:

curl -X POST

POST request options (arguments)

This table covers the fundamental arguments for constructing and sending POST requests with cURL, enabling a wide range of HTTP interactions from simple data submissions to complex file uploads and authentication handling:

Short Flag

Equivalent Long Flag

Argument Type


Example Usage




Specifies the HTTP method for the request. Primarily used to override or specify the method.





Attaches data to the body of the POST request. It can be used multiple times for multiple data pieces.

-d "username=user" -d "password=pass"




Adds a header to the request. It can also load headers from a file.

-H "Content-Type: application/json"




Used for sending multipart/form-data content. Suitable for text and file uploads.

-F "file=@path/to/file"



<data> or <filename>

Sends cookies with the request, specified directly or via a file.

-b "session=abc123" or -b cookies.txt




Designates a file to save cookies to after the request is complete. Useful for sessions.

-c cookies.txt




Instructs cURL to provide no output and exit early on server errors. Useful for scripts.




<data> or <filename>

Sends cookies with the request, specified directly or via a file.

-b "session=abc123" or -b cookies.txt




Designates a file to save cookies to after the request is complete. Useful for sessions.

-c cookies.txt




Instructs cURL to provide no output and exit early on server errors. Useful for scripts.





Includes the HTTP headers in the output. Useful for debugging or when headers are needed.





Allows connections to SSL sites without certificates or with incorrect certificates.





Follows HTTP redirects, redoing the request on the new location. Essential for some APIs.





Writes the output to a file instead of stdout. Useful for downloading files.

-o output.html




Operates in silent mode, not showing progress or error messages. Ideal for automation.





Provides detailed operation information, useful for troubleshooting.





Displays information on stdout after a completed transfer, formatted as specified.

-w "%{http_code}"

#1 Table. cURL POST Request-Response cycle

What is Request-Response cycle?

Here is a diagram illustrating the step-by-step process of sending a POST request with cURL and receiving a response from the server. This diagram includes decision points for handling different HTTP status codes, error handling, and retries.

Diagram: cURL POST Request-Response cycle

#2 Diagram. cURL POST Request-Response cycle. View fullView full

Looking for other relevant guides on cURL? We would recommend checking our other articles on this topic:

To find answers to other questions you may have, check out the official documentation for cURL⁵.

How to send data with a POST request?

To send data with your POST request, use the -d (or --data) option. This data is typically presented in the form of key-value pairs:

curl -X POST -d "key1=value1&key2=value2"

Remember, when adding data to your POST request, it's crucial to correctly specify the Content-Type header to match the type of data you're transmitting. If not, the server might struggle to process your request correctly. We'll dive into this in the sections below.

How to send JSON data?

What is JSON?

JSON (abbr. JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write and for machines to parse and generate. JSON is a text format that is completely language-independent but uses conventions familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.

When sending JSON data with cURL, it's important to set the Content-Type header to application/json to inform the server about the type of data being sent. This is done using the -H (or --header) option. The data itself is passed with the -d (or --data) option, formatted as a JSON string. Here's an example of how to send a POST request with JSON data:

curl -X POST -H "Content-Type: application/json" -d '{"key": "value", "number": 123, "boolean": true}'
  • -X POST specifies the request method.
  • -H "Content-Type: application/json" sets the header to indicate the resource's media type.
  • -d '{"key": "value", "number": 123, "boolean": true}' provides the JSON data to be sent to the server. This JSON string includes various data types commonly used in JSON, such as strings ("key": "value"), numbers ("number": 123), and booleans ("boolean": true).

How to post XML data?

What is XML?

XML (eXtensible Markup Language) is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. It’s a flexible way to create information formats and share structured data via various networks. XML's design goals emphasize simplicity, generality, and usability across the Internet. It’s a textual data format with strong support via Unicode for different languages. Although the design of XML focuses on documents, it’s widely used for the representation of arbitrary data structures, such as those used in web services.

First up, when posting XML data with cURL, you should set the Content-Type header to application/xml or text/xml, depending on the requirements of the server you're interacting with. This header is set using the -H flag, and the XML data itself is included with the -d option. Here’s how you can send a POST request with XML data:

curl -X POST -H "Content-Type: application/xml" -d '<person><name>John Smith</name><age>30</age></person>'
  • -X POST specifies that the HTTP method is POST.
  • -H "Content-Type: application/xml" sets the request header to inform the server that the data being sent is in XML format.
  • -d '<person><name>John Smith</name><age>30</age></person>' is the XML data payload. This example represents a simple XML document with a person element containing name and age elements.

XML is particularly useful for representing complex data structures or for applications where the preservation of document structure is important. It allows to define custom tags that provide flexibility in organizing and structuring data. XML's self-describing nature makes it an excellent choice for long-term data storage and configuration files, in addition to its widespread use in SOAP-based web services and other applications that require detailed document schemas.

How to send form data?

Form data is a common method of data transmission in web interactions, especially in HTTP POST requests. It's the standard approach for submitting web forms, accommodating diverse fields like text entries, choices, and file uploads. When utilizing cURL to dispatch form data, shaping the request to replicate a web browser's form submission process is key.

How to set MIME types for form data?

When submitting form data, the MIME type (media type or content type) used is application/x-www-form-urlencoded for standard text inputs. For more complex forms, particularly those involving file uploads, the MIME type should be multipart/form-data. Note that cURL automatically uses multipart/form-data when the -F flag is used.

How to send standard form fields?

To send standard text fields (like username and password inputs), you can use the -F (or --form) flag with cURL, which automatically sets the content type to multipart/form-data. Here's an example of submitting simple form fields:

curl -X POST -F "username=johndoe" -F "password=123456"
  • -F "username=johndoe" and -F "password=123456" represent the form data being sent.
  • Each -F adds another key-value pair to the request, mimicking the form fields in a web form.
  • Checkboxes and selections. For a form with checkboxes or selection dropdowns, use the -F flag for each option. If a checkbox is checked, include it with its value; otherwise, omit it.
  • File uploads are covered in the 3.4. Sending a File via the POST request section below.

How to submit advanced forms?

Forms often contain more than simple text inputs; they may include selections, checkboxes, and file uploads. Here’s how to handle various form elements with cURL:

How to use encoding and special characters?

When sending form data, ensure that special characters are properly encoded, especially in URLs and form field values. cURL handles some of this encoding automatically when using the -F flag. However, when manually crafting data with the -d flag and using application/x-www-form-urlencoded, pay special attention to characters that may require percent-encoding.

How to debug form data requests?

Debugging form data submissions with cURL can be facilitated using the -v (verbose) flag to view the request headers and body. This can help ensure that your form data is being sent as expected. We’ll cover the verbose mode in detail in the dedicated section below.

How to send a file via POST request?

Uploading files to a server is a common task in web development, especially when dealing with user-generated content (UGC) like images, documents, and other media. cURL simplifies this process with command-line options allowing efficient file uploads via POST requests. Here's a deeper dive into how to send a file using cURL, including different scenarios and considerations.

How to upload a basic file?

To upload a file with cURL, the -F (or --form) option is used to emulate a user filling out a form and attaching a file. This option automatically sets the Content-Type of the request to multipart/form-data, which is necessary for file uploads. Here's the basic syntax:

curl -X POST -F "file=@/path/to/yourfile.txt"
  • -F "file=@/path/to/yourfile.txt" indicates that cURL should include a file in the request.
  • The file part represents the form field name, while @/path/to/yourfile.txt specifies the local path to the file you want to upload.

For JSON files, it would look something like this:

curl -X POST -H "Content-Type: application/json" -d @data.json

How to use custom field names and upload multiple files?

The form field name (file in the previous example) should match what the server expects. You can upload multiple files by repeating the -F option with different field names and file paths:

curl -X POST -F "image=@/path/to/image.jpg" -F "document=@/path/to/document.pdf"

How to specify the MIME type?

Sometimes, you may need to explicitly set the MIME type of the file being uploaded, especially if it's not a common file type or when cURL doesn't correctly identify it. Use the ;type= syntax after the file path:

curl -X POST -F "file=@/path/to/file.custom;type=application/octet-stream"

How to upload file(s) with additional form data?

Often, file uploads are part of forms that include other data fields. You can mix file fields with standard data fields in the same cURL command:

curl -X POST -F "username=johndoe" -F "profile_pic=@/path/to/pic.jpg"

How to effectively manage large file uploads?

When uploading large files, you may encounter timeouts or need to monitor the progress of the upload. While cURL doesn’t have a built-in progress bar for POST requests, using the -v flag can provide insight into the request's progress. For timeout issues, the --max-time flag can increase the allowed time for the operation:

curl -X POST -F "file=@/path/to/" --max-time 600

How to securely upload files while considering potential security risks?

When uploading files, ensure that the endpoint is secured (preferably using HTTPS) to preventman-in-the-middle attacks⁶. You should also be cautious with the file paths and names you include in your cURL commands to avoid exposing sensitive information or accidentally uploading unintended files.

How to send images?

Uploading images is a frequent requirement in web development, especially for applications that allow UGC, such as profile pictures, galleries, or document scans. cURL provides a straightforward way to upload images to a server via POST requests, utilizing the same multipart/form-data content type used for uploading any file. This section expands on the specifics of sending image data, including handling different image formats and optimizing the upload process.

How to perform a basic image upload?

To upload an image using cURL, use the -F option, similar to how you would upload any other file. This method supports various image formats, including JPEG, PNG, GIF, and others, depending on the server's configuration:

curl -X POST -F "image=@/path/to/image.jpg"
  • image is the name of the form field that the server expects for the upload.
  • @/path/to/image.jpg specifies the local file path of the image you're uploading.

How do you specify the MIME type for an image upload?

While it's not always necessary, specifying the MIME type can be helpful, especially if the server enforces strict validations on the uploaded content. You can specify the MIME type by appending ;type=image/jpeg (or the appropriate MIME type for your image) to the file path:

curl -X POST -F "image=@/path/to/image.png;type=image/png"

How to upload multiple images in a single request?

If the server supports uploading multiple images in one request, you can repeat the -F option for each image. Ensure to use the correct form field names if the server expects each image under a different name:

curl -X POST -F "image1=@/path/to/image1.jpg" -F "image2=@/path/to/image2.jpg"

How to upload images with additional metadata?

Image uploads are often accompanied by additional metadata, such as titles, descriptions, or tags. You can include these in the same cURL command by adding more -F options for each piece of data:

curl -X POST -F "image=@/path/to/image.jpg" -F "title=Summer Vacation" -F "description=Family trip to Hawaii."

How to handle the upload of large images?

Large images may take longer to upload and could time out, especially on slow networks. To avoid timeouts, use the --max-time option to extend the allowed time for the upload process:

curl -X POST -F "image=@/path/to/largeimage.jpg" --max-time 120

What security and privacy considerations to keep in mind when uploading images?

When uploading images, consider the privacy and security implications, particularly if the images contain sensitive or personal information. Use HTTPS to protect the data in transit and ensure the server implements appropriate measures to secure the uploaded images against unauthorized access or disclosure.

How to optimize image uploads to enhance performance and reduce bandwidth usage?

Before uploading, consider optimizing images⁷ to reduce their size without significantly compromising quality. This can speed up the upload process and reduce bandwidth usage. Various tools and libraries can automate image optimization, such as ImageMagick⁸ for server-side scripts or client-side JavaScript libraries for web applications.

How to send authentication credentials using cURL for secure web interactions?

Authentication is a crucial aspect of interacting with secure web resources. When using cURL to send POST requests, there are various methods to include authentication credentials, depending on the security mechanisms implemented by the server. This section explores how to use cURL to send authentication credentials, covering basic authentication, token-based authentication, and OAuth.

How does basic authentication work?

Basic Authentication is a simple authentication scheme built into the HTTP protocol. It sends usernames and passwords encoded in Base64 over HTTP headers. cURL simplifies the process of sending these credentials using the -u or --user flag:

curl -u username:password -X POST

This method is straightforward but not the most secure, as the credentials are sent in plaintext (albeit Base64 encoded). It's strongly recommended to use HTTPS when employing basic authentication to prevent eavesdropping.

How does token-based authentication work?

Token-based authentication, such as bearer tokens in OAuth 2.0, is more secure and versatile than Basic Authentication. After obtaining a token from the authentication server, you include it in the request headers. cURL facilitates this with the -H flag:

curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -X POST

In this example, YOUR_ACCESS_TOKEN should be replaced with the actual token you've obtained through the authentication process.

How to use OAuth and OAuth2?

OAuth is a more complex authentication standard that allows users to approve one application interacting with another on their behalf without sharing their password. OAuth2 is the second version of this protocol and is widely adopted for its simplicity over the original OAuth.

Using cURL with OAuth typically involves obtaining an access token using the client credentials or another OAuth grant type. Once you have an access token, you use it similarly to the token-based authentication example above.

How to use cookie-based authentication?

Some applications use session cookies for authentication. After logging in, the server sets a cookie that must be included in subsequent requests. You can use cURL to store and send cookies with the -c (to save cookies to a file) and -b (to read cookies from a file) options:

# Log in and save the session cookie
curl -c cookies.txt -X POST -d "username=johndoe&password=123456"
# Use the session cookie for authenticated requests
curl -b cookies.txt -X POST

How to include an API key in the headers?

Some services use API keys for simplified access control, often passed as a query parameter or in the request headers. Here's how to include an API key in the headers with cURL:


Replace YOUR_API_KEY with your actual API key.

How to handle redirects in cURL?

Redirects are a standard mechanism on the web, instructing clients to fetch a resource from a different URL than the one initially requested. When using cURL to send POST requests, handling redirects properly ensures that your application can follow the server's response just as a web browser would. This section elaborates on handling redirects with cURL, including automatic follow-ups, dealing with changed request methods during redirects, and security considerations.

How to automatically follow redirects?

By default, cURL doesn’t follow redirect responses (like 301 Moved Permanently or 302 Found). To enable automatic following of redirects, use the -L or --location flag:

curl -L -X POST

With -L, if the server responds with a redirect, cURL will make a new request to the URL specified in the response's Location header.

How to maintain the request method and data across redirects?

When cURL follows a redirect using the -L flag, it changes the request method to GET if the redirect is a 301, 302, or 303 response. For 307 and 308 redirects, cURL retains the original request method and data. This behavior mimics the handling of redirects by web browsers but can be an issue when the initial POST data needs to be submitted to the redirect target.

To ensure that POST requests (and their data) are maintained across all redirects, you can use the --post301, --post302, and --post303 flags alongside -L. However, be cautious with this approach as it may not be expected by all servers and could lead to unintended behavior:

curl -L --post301 --post302 --post303 -X POST -d "data"

Security risks

Following redirects automatically can introduce security risks, especially when the redirect leads to an unexpected or untrusted domain. Consider these practices to mitigate risks:

  • Validate URLs. If possible, validate the URLs before following redirects, especially in automated scripts or applications.
  • Limit redirects. Use the --max-redirs option to limit the number of redirects cURL will follow, preventing infinite redirect loops:
curl -L --max-redirs 5 -X POST
  • HTTPS redirects. Be cautious about redirects from HTTPS to HTTP, as this downgrade can expose data. cURL follows these redirects by default, so you should consider the security implications in your application context.

How to deal with cookies across redirects?

When handling redirects, especially with authentication flows, you might need to manage cookies across different domains or paths. Use the -b option to send cookies and -c to store cookies provided in the response:

curl -L -b cookies.txt -c cookies.txt -X POST

In this command, -b cookies.txt tells cURL to use the existing cookies from the cookies.txt file for the request, while -c cookies.txt updates cookies.txt with any new cookies received in the response.

Correctly handling redirects with cURL ensures that your POST requests behave as intended, especially in workflows that involve authentication or form submissions. By using cURL's redirect options judiciously and being mindful of the security implications, you can make your scripts and applications more robust and secure.

How to add additional and custom HTTP headers to cURL request?

In many scenarios, especially when dealing with web APIs or performing complex web requests, it's necessary to include additional HTTP headers in your cURL requests. These headers can provide the server with more context about the request, such as content types, authentication information, custom data, and more. Understanding how to manipulate these headers is crucial for developers to ensure their requests are properly understood and handled by the server.

This diagram focuses on how headers are added, modified, and used in cURL POST requests. It provides a clear view of the role headers play in cURL POST requests and how they influence the processing of requests on the server side, including authentication, content handling, and custom logic execution:

Diagram: adding headers in cURL POST Requests

#3 Diagram. Adding headers in cURL POST Requests. View fullView full

How to add an authorization header?

When interacting with secured resources, you might need to include an authorization header. This header often carries tokens or credentials needed to authenticate the request:

curl -X POST -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

In this example, the Authorization header carries a bearer token, a common method used in OAuth2 authentication.

How to add a User-Agent header?

Some servers return different data based on the client's User-Agent string. You can customize this header to mimic different devices or browsers:

curl -X POST -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E5239e Safari/602.1"

This can be particularly useful for testing how your API responds to requests from different browsers or devices.

How to add an Accept header?

The Accept header tells the server the type of content you’re willing to receive in response. This is crucial for APIs that can return data in multiple formats:

curl -X POST -H "Accept: application/xml"

Here, the request specifies that it prefers to receive XML data in response.

How to add a Content-Length header?

While cURL automatically calculates and adds the Content-Length header, there might be cases where you need to override this behavior, especially when dealing with servers that have specific requirements:

curl -X POST -H "Content-Length: 0"

How to customize the Connection header?

You can control aspects of the HTTP connection itself using headers like Connection: keep-alive or Connection: close, although such cases are rare since cURL and the server usually manage connection behavior efficiently:

curl -X POST -H "Connection: close"

How to add a custom header?

To add a custom header to a cURL request, use the -H or --header flag followed by the header name and value. You can include multiple -H flags if you need to send multiple headers:

curl -X POST -H "Content-Type: application/json" -H "X-Custom-Header: Value"
  • Content-Type: application/json tells the server that the body of the request contains JSON data;
  • X-Custom-Header: Value is an example of a custom header that could be used for application-specific purposes.

How to save the response from a cURL request directly to a file?

When working with cURL to interact with web services or APIs, it's often useful to save the response from a server directly to a file. This is crucial for a variety of scenarios, such as logging responses, processing data offline, or simply preserving the output for review at a later time. cURL provides a straightforward way to achieve this, enhancing the tool's utility for developers and system administrators alike.

How to use the -o or --output option

To save a response to a file, you can use the -o (or --output) option followed by the path to where you want the file to be saved:

curl -X POST -d "param1=value1&param2=value2" -o response.txt

In this example, the response from the POST request to will be written to response.txt. If the file already exists, it will be overwritten.

How to append responses to a file?

If you want to append the response to an existing file rather than overwrite it, you can use shell redirection in Unix-like systems or the equivalent in other operating systems. Here's how to append to a file in a Unix-like system:

curl -X POST >> response.txt

Note that when using shell redirection to append or save output (> for overwrite, >> for append), you're capturing the standard output (stdout) of the cURL command. This means that any headers or verbose information sent to standard error (stderr) will not be captured in the file unless you explicitly redirect stderr to stdout using 2>&1. Here’s how this would look in a complete cURL request, including both the redirection of output to a file and capturing verbose information:

curl -v -o output.txt 2>&1
  • curl is the command to use cURL.
  • -v enables verbose mode, which sends detailed request and response information to stderr.
  • is the URL you are making the request to.
  • -o output.txt directs stdout (typically the response body) to a file named output.txt.
  • 2>&1 redirects stderr (where the verbose information goes) to stdout so that both the response data and the verbose details are captured in output.txt.

How to save headers alongside the body?

To save both the response headers and body to the same file, you can use the -i (or --include) option, which includes the HTTP response headers in the output:

curl -i -X POST -o response_with_headers.txt

Alternatively, if you want to save headers and body to separate files, you can use the -D option for headers:

curl -X POST -o body.txt -D headers.txt

How to handle binary files?

When downloading binary files, such as images or archives, ensure that you're writing the output in binary mode to prevent data corruption. cURL handles this automatically when using -o or -O, but it's an important consideration when redirecting output through the shell:

curl -X POST -o image.jpg

How to save file in verbose mode?

If you're using verbose mode (-v) to debug a request and want to save the output (including verbose information) to a file, you can redirect both stdout and stderr to the file:

curl -v -X POST -o response_verbose.txt 2>&1

What is verbose mode in cURL?

Verbose mode in cURL is an invaluable feature for developers and administrators, providing a detailed view of the request-response cycle. This mode outputs additional details to stderr about the HTTP conversation between the client (cURL) and the server. It includes information such as request headers, response headers, and the negotiation process of the protocols. Understanding and effectively using verbose mode can significantly aid in debugging, optimizing, and understanding web interactions.

How to enable verbose mode?

To enable verbose mode in cURL, you use the -v or --verbose flag. Here's a basic example:

curl -v -X POST

The -v flag instructs cURL to print detailed information about the request and response, including the full set of HTTP headers.

How verbose mode may help to debug a request?

Verbose mode provides insights into several aspects of the HTTP request and response process:

  • Connection details. Shows the IP address and port number of the server to which cURL connects.
  • TLS/SSL handshake. If connecting over HTTPS, verbose mode displays the TLS handshake process, including the chosen protocol version and cipher suite.
  • Request headers. Displays all headers sent to the server, which can help ensure that your request is formatted correctly.
  • Response headers. Lists all headers returned by the server, useful for debugging caching issues, cookies, and more.

Redirects. Shows the process of following redirects if the -L flag is used, including the response codes and the Location headers that guide the redirects.

How to debug request with verbose mode?

Verbose mode is particularly useful when debugging issues with API calls or web requests. For example, if an API call returns an unexpected response, verbose mode can help you see if the request headers were set correctly or if the server is responding with helpful error information.

How to combine verbose mode with output redirection?

When using verbose mode, the details are printed to stderr, while the actual content of the response is sent to stdout. This separation allows you to redirect them separately, for instance, saving the response to a file while still viewing the verbose output on the screen:

curl -v -X POST -o response.txt

To capture both the verbose data and the response in files, you can redirect stderr to a separate file:

curl -v -X POST -o response.txt 2> debug.txt

Mind the security

While the verbose mode is highly useful for debugging, be cautious with the output, especially in shared environments or when saving to logs, as it can contain sensitive information like authentication tokens or cookies.


In conclusion, this guide provides a comprehensive overview of how to use cURL to make POST requests, covering a wide range of scenarios from simple form submissions to complex multipart data uploads, handling authentication, etc. We've explored best practices for constructing cURL commands, including dynamic data generation, error handling, and output parsing for effective integration within larger scripts or automation workflows. With the knowledge of these techniques and the ability to address common errors and utilize alternatives, you’re well-equipped to leverage cURL's powerful features for interacting with REST APIs and automating web interactions. Whether you're testing APIs, automating data uploads, or integrating with web services, cURL is an indispensable tool in the developer's toolkit, offering the flexibility and depth to meet a wide array of web request needs. Remember, the key to effective cURL usage lies in understanding the specific requirements of your API endpoints and refining your requests to ensure reliable and efficient data exchange.

How would you improve this guide? Just let us know via our 24/7 LiveChat, Discord, Linkedin, and email. We will send your points to the author(s) of this guide. Our experts will evaluate your suggestions and if those will be essential and valuable to our readers, you will receive a special gift from us!

Information sources


About the author

Martin Ganchev

VP Enterprise Partnerships

Martin, aka the driving force behind our business expansion, is extremely passionate about exploring fresh opportunities, fostering lasting relationships in the proxy market, and, of course, sharing his insights with you.


All information on Smartproxy Blog is provided on an "as is" basis and for informational purposes only. We make no representation and disclaim all liability with respect to your use of any information contained on Smartproxy Blog or any third-party websites that may be linked therein.

Frequently asked questions

What is the difference between POST and GET cURL?

In the context of cURL, a tool for making requests to URLs from the command line or scripts, the difference between POST and GET requests primarily lies in their purpose and how data is sent to the server:

  • GET request. A GET request used to retrieve data from a specified resource. Data is sent as URL parameters. GET requests are idempotent, meaning they can be repeated multiple times without changing the result beyond the initial application state change. In cURL, a GET request is made simply by specifying the URL or explicitly using -X GET. Data sent in a GET request is appended to the URL as query parameters. .
  • POST request. A POST request used to send data to a server to create or update a resource. The data is sent in the request body rather than in the URL. This allows more data to be sent because it’s not limited by the URL length. It's also more secure for sensitive data, as the data doesn’t appear in web server logs or browser history. In cURL, a POST request is made using -X POST and -d to include the data.

In summary, the key difference in cURL between POST and GET requests is how data is sent and the intended use of each request type: GET requests are for retrieving data without side effects, while POST requests are for submitting data to be processed by the server, potentially changing server state or creating new resources.

What are cURL alternatives for POST requests?

Are cURL flags or command line options (arguments) case-sensitive?

How to handle rate limits and retries with cURL?

Related articles


How to Send a cURL GET Request

Tired of gathering data inefficiently? Well, have you tried cURL? It’s a powerful and versatile command-line tool for transferring data with URLs. Its simplicity and wide range of capabilities make it a go-to solution for developers, data analysts, and businesses alike. Simply put, the cURL GET request method is the cornerstone of web scraping and data gathering. It enables you to access publicly available data without the need for complex coding or expensive software. In this blog post, we’ll explain how to send cURL GET requests, so you’re ready to harness its fullest potential.

Dominykas Niaura

Jan 02, 2024

7 min read

© 2018-2024, All Rights Reserved