EN
English
简体中文
Log inGet started for free

Blog

Proxies

what-is-a-curl-post-request-and-how-to-send-it

What is a cURL POST Request and How to Send It?

How to send a cURL POST request

author Kael Odin
Kael Odin
Last updated on
2026-03-02
12 min read
📌 Key Takeaways
  • cURL lets you send HTTP POST requests directly from the command line, which is ideal for quickly testing and debugging modern HTTP APIs.
  • You can use cURL POST requests to send form fields, JSON payloads, and files, and to add headers, authentication, and proxy settings.
  • Most “curl doesn’t work” issues come from quoting problems, invalid JSON, missing headers, or using the wrong HTTP method — all of which are easy to fix once you know what to check.

When you integrate with modern APIs in 2026, you will inevitably run into curl examples in documentation, GitHub issues, and Stack Overflow answers. Understanding how a cURL POST request works is one of the fastest ways to debug HTTP traffic and reproduce client behavior without writing extra code.

In this guide, we will walk through what a POST request actually does, how to craft reliable cURL commands, and how to send real-world payloads such as form data, JSON, and file uploads. We will also cover common errors and the exact flags you can use to understand what is going on under the hood, so you can confidently move between browser-based tools like Postman and low-level debugging with the terminal.

What is cURL?

cURL (short for “Client URL”) is a command-line tool and library for transferring data to and from servers. It supports a long list of protocols, but for web developers the most important one is HTTP(S).

You can think of cURL as a programmable browser without a GUI: it can send requests, follow redirects, handle cookies, add headers, and show you the raw response exactly as the server sends it. As of 2026, curl also has mature support for HTTP/2 and HTTP/3 where the server and TLS stack allow it, which makes it a realistic way to simulate production traffic.

curl https://httpbin.org/get

The example above sends a simple GET request. In the rest of this article we will focus on POST requests, which are used when you need to send data to the server.

If you want to explore everything curl can do beyond POST requests, the official curl documentation and HTTP method reference such as MDN's POST guide are excellent companions to this article.

Why developers still rely on cURL in 2026

Even though graphical tools like Postman, Insomnia, and API dashboards are popular, experienced engineers still keep curl in their daily toolkit:

  • Fast debugging – reproduce an issue from logs or documentation with a single command, without opening a UI.
  • Scriptability – automate regression tests, health checks, and CI smoke tests with shell scripts that call curl.
  • Reproducible examples – share a one-line curl snippet in tickets, runbooks, or documentation so the next engineer can replay the exact same request.

What is a cURL POST request?

An HTTP POST request sends data in the request body instead of (or in addition to) the URL query string. This is how you typically submit forms, create resources in REST APIs, or send login credentials.

A minimal cURL POST request looks like this:

curl -X POST -d "name=Alice&role=developer" https://httpbin.org/post

Here is what each part means:

  • curl – starts the cURL program.
  • -X POST – explicitly sets the HTTP method to POST. (In many cases cURL will infer POST automatically when you send -d.)
  • -d “name=Alice&role=developer” – sends data in the request body, using URL-encoded form format by default.
  • https://httpbin.org/post – the target URL / API endpoint.

Core cURL POST options at a glance

Option Meaning Typical usage
-X Specify the HTTP method (POST, PUT, PATCH, DELETE…) -X POST when you want to be explicit about the method.
-d Send data in the request body -d "name=Alice&role=developer" or -d '{"name":"Alice"}'
-H Add a custom HTTP header -H "Content-Type: application/json"
-o Write response body to a file -o response.json
-F Send multipart form data, including file uploads -F "file=@/path/to/file.txt"
-L Follow redirects Useful for login forms or APIs that redirect after POST.
-u HTTP Basic authentication -u "username:password"

Sending different types of POST data with cURL

1. Simulating HTML form submissions

Many web applications still send form data as application/x-www-form-urlencoded, the same format browsers use by default.

curl -X POST \ -d "username=testuser&password=secret123" \ https://example.com/login

cURL automatically sets the appropriate Content-Type header when you use -d with a URL-encoded string. This makes it easy to reproduce login forms or simple POST endpoints during debugging.

If the server redirects after login (for example from /login to /dashboard), use -L to follow the redirect:

curl -L -X POST \ -d "username=testuser&password=secret123" \ https://example.com/login

2. Sending JSON payloads

Modern APIs usually expect JSON instead of form data. With cURL, you just have to do two things:

  1. Set the Content-Type header to application/json.
  2. Pass a valid JSON string to -d (or --data).
curl -X POST \ -H "Content-Type: application/json" \ -d '{"email":"user@example.com","password":"securepassword"}' \ https://api.example.com/login
Tip: On Linux and macOS, single quotes around the JSON body are usually safer because they prevent the shell from interpreting double quotes or special characters. On Windows CMD or PowerShell, you may need to switch the quote style.

3. Uploading files with cURL

To upload files, use the -F option, which encodes the request as multipart/form-data. This is the same format browsers use for file inputs in HTML forms.

curl -X POST \ -F "upload_file=@/path/to/report.csv" \ -F "description=Monthly KPI report" \ https://example.com/upload

The @ symbol tells cURL to read data from a local file. You can mix file fields and simple text fields in the same request.

Adding headers and authentication

Adding custom headers

Real-world APIs almost always require extra headers — for example, API keys, versioning headers, or content negotiation.

curl -X POST \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Thordata","plan":"enterprise"}' \ https://api.example.com/accounts

Using Basic Authentication

Some internal tools and staging environments use HTTP Basic Auth. You can supply the credentials directly via -u:

curl -X POST \ -u "admin:supersecret" \ -d "action=flush-cache" \ https://admin.example.com/maintenance

Working with proxies

When you need to test how your POST requests behave from different regions or through a proxy network, you can route traffic via a proxy:

curl -X POST \ -x http://proxy.example.com:8080 \ -H "Content-Type: application/json" \ -d '{"event":"signup","source":"campaign-123"}' \ https://api.example.com/events

Using high-quality residential or rotating proxies can help you simulate real-user behavior, avoid rate-limiting patterns, and test geo-specific API behavior more accurately.

Saving responses and testing APIs efficiently

During debugging, you often want to persist responses to a file and inspect them using additional tools.

curl -X POST \ -H "Content-Type: application/json" \ -d '{"query":"status"}' \ -o status-response.json \ https://api.example.com/status

If the API returns JSON, you can pretty-print it with jq:

curl -X POST \ -H "Content-Type: application/json" \ -d '{"query":"status"}' \ https://api.example.com/status | jq

For more advanced test setups, teams often wrap curl calls in shell scripts or CI jobs, then combine them with monitoring and alerting. This makes it easy to turn a manual troubleshooting step into a repeatable check that runs every time you deploy.

Common cURL POST errors and how to fix them

“Could not resolve host”

This error usually means there is a typo in the domain, the host does not exist, or your DNS/network configuration is broken.

  • Double-check the URL and protocol (https:// vs http://).
  • Attempt a simple curl https://example.com to confirm basic connectivity.

“Unsupported protocol”

This appears when you use a protocol that your cURL build does not support, or when the URL string is malformed (for example, missing http://).

Make sure you are using http:// or https:// unless you explicitly intend to use FTP, SMTP, or another protocol and your environment supports it.

HTTP 400 / 401 / 403 / 415

  • 400 Bad Request – often caused by malformed JSON, missing required fields, or sending parameters with the wrong type.
  • 401 Unauthorized / 403 Forbidden – usually an authentication or permission issue; check your token, credentials, or allowed scopes.
  • 415 Unsupported Media Type – the server does not accept your Content-Type; check the API docs for the required format.
Debug like a pro: Add -v (verbose) or even --trace-ascii debug.log to your cURL command to inspect raw request and response headers. This often reveals mismatched headers, redirects, or proxy behavior that is hard to see otherwise.

Best practices for reliable cURL POST requests

  • Keep one “golden” example per API endpoint that you know works and commit it to your repository for future debugging.
  • Always set Content-Type explicitly when sending JSON or non-default payloads.
  • Use environment variables for secrets like API keys instead of hardcoding them into your commands.
  • Prefer -L when working with login flows or endpoints that redirect.
  • Log responses by writing them to files when debugging production issues, so you can share them with your team securely.

Conclusion

cURL POST requests are one of the most versatile tools in a developer’s toolbox. With a single command, you can reproduce browser forms, hit REST endpoints, submit JSON payloads, or upload files — all without writing a new script.

Once you understand how options like -d, -H, -F, -L, and -u work together, debugging HTTP issues becomes dramatically faster. Start by copying a working example from this guide, adjust the URL and payload for your own API, and then iterate using verbose mode and logs until the server responds exactly the way you expect.

Get started for free

Frequently asked questions

What is a cURL POST request used for?

A cURL POST request is used to send data in the body of an HTTP request, typically to submit forms, create or update resources in an API, send JSON payloads, or upload files. It is especially useful for testing API endpoints and reproducing client behavior directly from the command line.

How do I send JSON with a cURL POST request?

Add a Content-Type: application/json header with -H and pass a valid JSON string to -d, for example: curl -X POST -H "Content-Type: application/json" -d '{"email":"user@example.com","password":"secret"}' https://api.example.com/login. Make sure your JSON is properly quoted for your shell.

How can I debug a failing cURL POST request?

Start by adding the -v flag to see request and response headers, confirm the URL and HTTP method, and compare your payload and headers with the API documentation. If the server responds with 4xx or 5xx codes, look at the response body for error messages and check for issues like invalid JSON, missing authentication, or wrong Content-Type.

About the author

Kael is a Senior Technical Copywriter at Thordata. He works closely with data engineers and API platform teams to document best practices for sending and debugging HTTP requests at scale. His focus is on turning low-level protocol details into practical workflows that developers can apply in day-to-day debugging.

The thordata Blog offers all its content in its original form and solely for informational intent. We do not offer any guarantees regarding the information found on the thordata Blog or any external sites that it may direct you to. It is essential that you seek legal counsel and thoroughly examine the specific terms of service of any website before engaging in any scraping endeavors, or obtain a scraping permit if required.