Mastering cURL POST Requests for Proxy & API Testing

Sarah Whitmore

Last edited on May 4, 2025
Last edited on May 4, 2025

Tool Guides

Diving into cURL for POST Requests

Meet cURL: your trusty command-line sidekick for transferring data using various network protocols. Think of it as a Swiss Army knife for web requests. It's likely already living in your system's terminal, especially if you're on a recent version of macOS or Windows (10 and up).

While graphical tools like Postman offer a visual interface for similar tasks, cURL operates closer to the metal. This direct approach makes it incredibly reliable and a go-to for scripting, automation, or anytime you need precise control over your web interactions.

Getting cURL Ready:

As mentioned, macOS and modern Windows usually have cURL built-in. Many Linux distributions include it too, but if not, adding it is typically straightforward. On Debian/Ubuntu systems, you can usually install it using:

sudo apt update && sudo apt install curl

For older Windows versions, you might need to grab an installation package from the official cURL website. Check out our guide on downloading files with cURL for pointers on installation if needed.

Once installed (or if it was already there), you can verify it by opening your terminal or command prompt and typing:

curl --version

This command should output the cURL version number along with supported features and protocols. Quick Tip for Windows Users: Stick to the standard Command Prompt (cmd.exe) rather than PowerShell for running the cURL commands shown here, as PowerShell sometimes requires different syntax for quoting and special characters.

Constructing a Basic cURL POST Request

Using cURL generally follows a pattern: you call the curl command, specify options (flags), provide the target URL, and add any other necessary parameters like headers or data.

curl

To send a POST request, which is typically used to submit data to a server (like filling out a form or sending instructions to an API), you need a few key ingredients:

  1. Specify the Method: Use the -X flag followed by POST. This tells cURL explicitly that you intend to make a POST request. (While cURL can sometimes infer POST if data is present, being explicit is good practice).

  2. Include the Data: Use the -d flag followed by the data payload you want to send, enclosed in quotes. Every POST request needs *some* data. The format depends entirely on what the receiving server or API expects.

  3. Provide the URL: The destination endpoint where the request should be sent.

Let's try a simple example using httpbin.org, a handy service for testing HTTP requests:

curl \
  -X POST \
  https://httpbin.org/post \
  -d "message=HelloFromEvomi"

Often, APIs require data to be sent in JSON format. To do this, you also need to tell the server you're sending JSON using a header (more on headers next!) and format your data string accordingly:

curl \
  -X POST \
  https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -d '{"user":"test_account", "status":"active", "id":123}'

Notice the single quotes around the JSON data – this often helps prevent shell interpretation issues with the double quotes inside the JSON itself.

Enhancing Your POST Requests: Headers and Data

Real-world API interactions often demand more than just the basic method and data. Headers play a crucial role in providing metadata about your request.

You add headers using the -H flag, followed by the header string in "Header-Name: Value" format. You can use multiple -H flags for multiple headers:

curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "User-Agent: MyAwesomeApp/1.0" \
  -d '{"item":"widget", "quantity":5}'

Authentication is another common requirement. Many APIs need to know who you are before processing your request. Two frequent methods are:

  • Basic Authentication: Sending a username and password. cURL makes this easy with the -u or --user flag:

curl \
  -u "your_username:your_password" \
  -X POST \
  https://api.example.com/data \
  -d '{"info":"some_data"}'
  • Token-Based Authentication: Sending a special token (like an API key or OAuth token) in a header, often the Authorization header:

curl -X POST \
  https://api.example.com/action \
  -H "Authorization: Bearer YOUR_SECRET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"perform_task"}'

Sometimes, the data you need to POST exists in a file. Instead of pasting the content into the command line, you can tell cURL to read it directly using -d @ followed by the file path:

curl \
    -X POST \
    https://httpbin.org/post \
    -H "Content-Type: text/plain" \
    --data-binary

(Using --data-binary ensures the file content is sent exactly as-is, without any processing by cURL, which is often preferred).

Using Proxies with cURL POST Requests

Proxies act as intermediaries for your requests, which is invaluable for tasks like testing APIs from different geographic locations, managing multiple accounts, or enhancing privacy. cURL makes using proxies straightforward with the -x (or --proxy) flag.

You provide the proxy server address and port after the flag. If the proxy requires authentication, include it in the format protocol://user:password@host:port.

For instance, if you were testing an API using one of Evomi's residential proxies, the command might look something like this (using placeholder credentials and endpoint):

curl \
  -x http://your_evomi_user:your_evomi_pass@rp.evomi.com:1000 \
  -X POST \
  https://api.targetservice.com/submit \
  -H "Content-Type: application/json" \
  -d '{"location_test":"ch", "value":42}'

This routes your POST request through the specified Evomi residential proxy server. Evomi offers a range of ethically sourced proxy solutions, including Residential, Mobile, Datacenter, and Static ISP proxies, allowing you to tailor your connection precisely for your testing or automation needs. We even offer a free trial if you'd like to test how seamlessly cURL integrates with our proxy network.

Deciphering cURL Responses and Handling Errors

When you run a cURL command, it prints the response body received from the server directly to your terminal. Sometimes, this is exactly what you want, but for debugging, you often need more information.

Two helpful flags are:

  • -i or --include: Shows the HTTP response headers along with the body.

  • -v or --verbose: Provides detailed information about the entire connection process, including request headers sent, TLS handshake details, and response headers. This is incredibly useful for troubleshooting connection or request formatting issues.

The server's response will typically include an HTTP status code. You'll learn to recognize common ones:

  • 2xx (e.g., 200 OK, 201 Created): Success!

  • 4xx (e.g., 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found): Client-side error – something is likely wrong with your request (bad data format, missing authentication, wrong URL, etc.).

  • 5xx (e.g., 500 Internal Server Error, 503 Service Unavailable): Server-side error – the problem is likely on the server you're contacting.

If you send an invalid request, the response body often contains error details. For example, sending a POST to a URL expecting JSON but providing plain text might result in a 400 Bad Request with a message like:

{
  "error": "Invalid JSON payload received"
}

Or attempting to access a protected endpoint without proper credentials might give a 401 Unauthorized response. Some APIs provide detailed custom error messages, while others might use more standard HTTP error codes.

Putting It All Together

While cURL boasts a vast array of options (check the official cURL documentation for the full deep dive), many common POST requests involve combining a few key elements. A typical structure might look like this, incorporating the method, headers, authentication (via token), and data:

curl -X POST https://api.yourservice.com/v1/process \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"input_data": "value1", "parameter": "config_a"}' \
    -v

This example explicitly sets the POST method, includes authentication and content type headers, specifies the JSON payload, requests a JSON response (via `Accept`), and adds `-v` for verbose output to help during testing.

Mastering cURL POST requests opens up a world of possibilities for interacting with APIs, automating tasks, and testing web services directly from your command line. Don't hesitate to experiment!

If you found this useful, you might also be interested in our guide to performing cURL GET requests.

Diving into cURL for POST Requests

Meet cURL: your trusty command-line sidekick for transferring data using various network protocols. Think of it as a Swiss Army knife for web requests. It's likely already living in your system's terminal, especially if you're on a recent version of macOS or Windows (10 and up).

While graphical tools like Postman offer a visual interface for similar tasks, cURL operates closer to the metal. This direct approach makes it incredibly reliable and a go-to for scripting, automation, or anytime you need precise control over your web interactions.

Getting cURL Ready:

As mentioned, macOS and modern Windows usually have cURL built-in. Many Linux distributions include it too, but if not, adding it is typically straightforward. On Debian/Ubuntu systems, you can usually install it using:

sudo apt update && sudo apt install curl

For older Windows versions, you might need to grab an installation package from the official cURL website. Check out our guide on downloading files with cURL for pointers on installation if needed.

Once installed (or if it was already there), you can verify it by opening your terminal or command prompt and typing:

curl --version

This command should output the cURL version number along with supported features and protocols. Quick Tip for Windows Users: Stick to the standard Command Prompt (cmd.exe) rather than PowerShell for running the cURL commands shown here, as PowerShell sometimes requires different syntax for quoting and special characters.

Constructing a Basic cURL POST Request

Using cURL generally follows a pattern: you call the curl command, specify options (flags), provide the target URL, and add any other necessary parameters like headers or data.

curl

To send a POST request, which is typically used to submit data to a server (like filling out a form or sending instructions to an API), you need a few key ingredients:

  1. Specify the Method: Use the -X flag followed by POST. This tells cURL explicitly that you intend to make a POST request. (While cURL can sometimes infer POST if data is present, being explicit is good practice).

  2. Include the Data: Use the -d flag followed by the data payload you want to send, enclosed in quotes. Every POST request needs *some* data. The format depends entirely on what the receiving server or API expects.

  3. Provide the URL: The destination endpoint where the request should be sent.

Let's try a simple example using httpbin.org, a handy service for testing HTTP requests:

curl \
  -X POST \
  https://httpbin.org/post \
  -d "message=HelloFromEvomi"

Often, APIs require data to be sent in JSON format. To do this, you also need to tell the server you're sending JSON using a header (more on headers next!) and format your data string accordingly:

curl \
  -X POST \
  https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -d '{"user":"test_account", "status":"active", "id":123}'

Notice the single quotes around the JSON data – this often helps prevent shell interpretation issues with the double quotes inside the JSON itself.

Enhancing Your POST Requests: Headers and Data

Real-world API interactions often demand more than just the basic method and data. Headers play a crucial role in providing metadata about your request.

You add headers using the -H flag, followed by the header string in "Header-Name: Value" format. You can use multiple -H flags for multiple headers:

curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "User-Agent: MyAwesomeApp/1.0" \
  -d '{"item":"widget", "quantity":5}'

Authentication is another common requirement. Many APIs need to know who you are before processing your request. Two frequent methods are:

  • Basic Authentication: Sending a username and password. cURL makes this easy with the -u or --user flag:

curl \
  -u "your_username:your_password" \
  -X POST \
  https://api.example.com/data \
  -d '{"info":"some_data"}'
  • Token-Based Authentication: Sending a special token (like an API key or OAuth token) in a header, often the Authorization header:

curl -X POST \
  https://api.example.com/action \
  -H "Authorization: Bearer YOUR_SECRET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"perform_task"}'

Sometimes, the data you need to POST exists in a file. Instead of pasting the content into the command line, you can tell cURL to read it directly using -d @ followed by the file path:

curl \
    -X POST \
    https://httpbin.org/post \
    -H "Content-Type: text/plain" \
    --data-binary

(Using --data-binary ensures the file content is sent exactly as-is, without any processing by cURL, which is often preferred).

Using Proxies with cURL POST Requests

Proxies act as intermediaries for your requests, which is invaluable for tasks like testing APIs from different geographic locations, managing multiple accounts, or enhancing privacy. cURL makes using proxies straightforward with the -x (or --proxy) flag.

You provide the proxy server address and port after the flag. If the proxy requires authentication, include it in the format protocol://user:password@host:port.

For instance, if you were testing an API using one of Evomi's residential proxies, the command might look something like this (using placeholder credentials and endpoint):

curl \
  -x http://your_evomi_user:your_evomi_pass@rp.evomi.com:1000 \
  -X POST \
  https://api.targetservice.com/submit \
  -H "Content-Type: application/json" \
  -d '{"location_test":"ch", "value":42}'

This routes your POST request through the specified Evomi residential proxy server. Evomi offers a range of ethically sourced proxy solutions, including Residential, Mobile, Datacenter, and Static ISP proxies, allowing you to tailor your connection precisely for your testing or automation needs. We even offer a free trial if you'd like to test how seamlessly cURL integrates with our proxy network.

Deciphering cURL Responses and Handling Errors

When you run a cURL command, it prints the response body received from the server directly to your terminal. Sometimes, this is exactly what you want, but for debugging, you often need more information.

Two helpful flags are:

  • -i or --include: Shows the HTTP response headers along with the body.

  • -v or --verbose: Provides detailed information about the entire connection process, including request headers sent, TLS handshake details, and response headers. This is incredibly useful for troubleshooting connection or request formatting issues.

The server's response will typically include an HTTP status code. You'll learn to recognize common ones:

  • 2xx (e.g., 200 OK, 201 Created): Success!

  • 4xx (e.g., 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found): Client-side error – something is likely wrong with your request (bad data format, missing authentication, wrong URL, etc.).

  • 5xx (e.g., 500 Internal Server Error, 503 Service Unavailable): Server-side error – the problem is likely on the server you're contacting.

If you send an invalid request, the response body often contains error details. For example, sending a POST to a URL expecting JSON but providing plain text might result in a 400 Bad Request with a message like:

{
  "error": "Invalid JSON payload received"
}

Or attempting to access a protected endpoint without proper credentials might give a 401 Unauthorized response. Some APIs provide detailed custom error messages, while others might use more standard HTTP error codes.

Putting It All Together

While cURL boasts a vast array of options (check the official cURL documentation for the full deep dive), many common POST requests involve combining a few key elements. A typical structure might look like this, incorporating the method, headers, authentication (via token), and data:

curl -X POST https://api.yourservice.com/v1/process \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"input_data": "value1", "parameter": "config_a"}' \
    -v

This example explicitly sets the POST method, includes authentication and content type headers, specifies the JSON payload, requests a JSON response (via `Accept`), and adds `-v` for verbose output to help during testing.

Mastering cURL POST requests opens up a world of possibilities for interacting with APIs, automating tasks, and testing web services directly from your command line. Don't hesitate to experiment!

If you found this useful, you might also be interested in our guide to performing cURL GET requests.

Diving into cURL for POST Requests

Meet cURL: your trusty command-line sidekick for transferring data using various network protocols. Think of it as a Swiss Army knife for web requests. It's likely already living in your system's terminal, especially if you're on a recent version of macOS or Windows (10 and up).

While graphical tools like Postman offer a visual interface for similar tasks, cURL operates closer to the metal. This direct approach makes it incredibly reliable and a go-to for scripting, automation, or anytime you need precise control over your web interactions.

Getting cURL Ready:

As mentioned, macOS and modern Windows usually have cURL built-in. Many Linux distributions include it too, but if not, adding it is typically straightforward. On Debian/Ubuntu systems, you can usually install it using:

sudo apt update && sudo apt install curl

For older Windows versions, you might need to grab an installation package from the official cURL website. Check out our guide on downloading files with cURL for pointers on installation if needed.

Once installed (or if it was already there), you can verify it by opening your terminal or command prompt and typing:

curl --version

This command should output the cURL version number along with supported features and protocols. Quick Tip for Windows Users: Stick to the standard Command Prompt (cmd.exe) rather than PowerShell for running the cURL commands shown here, as PowerShell sometimes requires different syntax for quoting and special characters.

Constructing a Basic cURL POST Request

Using cURL generally follows a pattern: you call the curl command, specify options (flags), provide the target URL, and add any other necessary parameters like headers or data.

curl

To send a POST request, which is typically used to submit data to a server (like filling out a form or sending instructions to an API), you need a few key ingredients:

  1. Specify the Method: Use the -X flag followed by POST. This tells cURL explicitly that you intend to make a POST request. (While cURL can sometimes infer POST if data is present, being explicit is good practice).

  2. Include the Data: Use the -d flag followed by the data payload you want to send, enclosed in quotes. Every POST request needs *some* data. The format depends entirely on what the receiving server or API expects.

  3. Provide the URL: The destination endpoint where the request should be sent.

Let's try a simple example using httpbin.org, a handy service for testing HTTP requests:

curl \
  -X POST \
  https://httpbin.org/post \
  -d "message=HelloFromEvomi"

Often, APIs require data to be sent in JSON format. To do this, you also need to tell the server you're sending JSON using a header (more on headers next!) and format your data string accordingly:

curl \
  -X POST \
  https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -d '{"user":"test_account", "status":"active", "id":123}'

Notice the single quotes around the JSON data – this often helps prevent shell interpretation issues with the double quotes inside the JSON itself.

Enhancing Your POST Requests: Headers and Data

Real-world API interactions often demand more than just the basic method and data. Headers play a crucial role in providing metadata about your request.

You add headers using the -H flag, followed by the header string in "Header-Name: Value" format. You can use multiple -H flags for multiple headers:

curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "User-Agent: MyAwesomeApp/1.0" \
  -d '{"item":"widget", "quantity":5}'

Authentication is another common requirement. Many APIs need to know who you are before processing your request. Two frequent methods are:

  • Basic Authentication: Sending a username and password. cURL makes this easy with the -u or --user flag:

curl \
  -u "your_username:your_password" \
  -X POST \
  https://api.example.com/data \
  -d '{"info":"some_data"}'
  • Token-Based Authentication: Sending a special token (like an API key or OAuth token) in a header, often the Authorization header:

curl -X POST \
  https://api.example.com/action \
  -H "Authorization: Bearer YOUR_SECRET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"perform_task"}'

Sometimes, the data you need to POST exists in a file. Instead of pasting the content into the command line, you can tell cURL to read it directly using -d @ followed by the file path:

curl \
    -X POST \
    https://httpbin.org/post \
    -H "Content-Type: text/plain" \
    --data-binary

(Using --data-binary ensures the file content is sent exactly as-is, without any processing by cURL, which is often preferred).

Using Proxies with cURL POST Requests

Proxies act as intermediaries for your requests, which is invaluable for tasks like testing APIs from different geographic locations, managing multiple accounts, or enhancing privacy. cURL makes using proxies straightforward with the -x (or --proxy) flag.

You provide the proxy server address and port after the flag. If the proxy requires authentication, include it in the format protocol://user:password@host:port.

For instance, if you were testing an API using one of Evomi's residential proxies, the command might look something like this (using placeholder credentials and endpoint):

curl \
  -x http://your_evomi_user:your_evomi_pass@rp.evomi.com:1000 \
  -X POST \
  https://api.targetservice.com/submit \
  -H "Content-Type: application/json" \
  -d '{"location_test":"ch", "value":42}'

This routes your POST request through the specified Evomi residential proxy server. Evomi offers a range of ethically sourced proxy solutions, including Residential, Mobile, Datacenter, and Static ISP proxies, allowing you to tailor your connection precisely for your testing or automation needs. We even offer a free trial if you'd like to test how seamlessly cURL integrates with our proxy network.

Deciphering cURL Responses and Handling Errors

When you run a cURL command, it prints the response body received from the server directly to your terminal. Sometimes, this is exactly what you want, but for debugging, you often need more information.

Two helpful flags are:

  • -i or --include: Shows the HTTP response headers along with the body.

  • -v or --verbose: Provides detailed information about the entire connection process, including request headers sent, TLS handshake details, and response headers. This is incredibly useful for troubleshooting connection or request formatting issues.

The server's response will typically include an HTTP status code. You'll learn to recognize common ones:

  • 2xx (e.g., 200 OK, 201 Created): Success!

  • 4xx (e.g., 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found): Client-side error – something is likely wrong with your request (bad data format, missing authentication, wrong URL, etc.).

  • 5xx (e.g., 500 Internal Server Error, 503 Service Unavailable): Server-side error – the problem is likely on the server you're contacting.

If you send an invalid request, the response body often contains error details. For example, sending a POST to a URL expecting JSON but providing plain text might result in a 400 Bad Request with a message like:

{
  "error": "Invalid JSON payload received"
}

Or attempting to access a protected endpoint without proper credentials might give a 401 Unauthorized response. Some APIs provide detailed custom error messages, while others might use more standard HTTP error codes.

Putting It All Together

While cURL boasts a vast array of options (check the official cURL documentation for the full deep dive), many common POST requests involve combining a few key elements. A typical structure might look like this, incorporating the method, headers, authentication (via token), and data:

curl -X POST https://api.yourservice.com/v1/process \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"input_data": "value1", "parameter": "config_a"}' \
    -v

This example explicitly sets the POST method, includes authentication and content type headers, specifies the JSON payload, requests a JSON response (via `Accept`), and adds `-v` for verbose output to help during testing.

Mastering cURL POST requests opens up a world of possibilities for interacting with APIs, automating tasks, and testing web services directly from your command line. Don't hesitate to experiment!

If you found this useful, you might also be interested in our guide to performing cURL GET requests.

Author

Sarah Whitmore

Digital Privacy & Cybersecurity Consultant

About Author

Sarah is a cybersecurity strategist with a passion for online privacy and digital security. She explores how proxies, VPNs, and encryption tools protect users from tracking, cyber threats, and data breaches. With years of experience in cybersecurity consulting, she provides practical insights into safeguarding sensitive data in an increasingly digital world.

Like this article? Share it.
You asked, we answer - Users questions:
How does cURL handle redirects (like 301 or 302) when making a POST request?+
How can I set a timeout for a cURL POST request if the API or proxy server takes too long to respond?+
The article shows sending data with `-d`. How do I send data as `multipart/form-data`, like submitting an HTML form with a file upload, using cURL?+
Can I manage cookies with cURL POST requests for API testing that requires maintaining a session?+
Does the `-x` proxy flag mentioned for HTTP proxies also work with other proxy protocols like SOCKS5?+

In This Article

Read More Blogs