As a QA automation engineer, cURL is your Swiss Army knife for API testing. Whether you're debugging a failing endpoint, exploring a new API, or quickly validating responses before writing automated tests, cURL gives you direct, no-nonsense access to HTTP interactions right from your terminal. Master these five essential commands, and you'll spend less time wrestling with heavy tools and more time actually testing.
The GET request is your bread and butter for API testing, and most real-world APIs require some form of authentication. The basic syntax is straightforward:
curl -H "Authorization: Bearer YOUR_TOKEN" https://api.example.com/users
For Bearer token authentication (common with OAuth 2.0 and JWT), use the -H flag to add the Authorization header. If you're working with API key authentication, it might look like this instead:
curl -H "X-API-Key: YOUR_API_KEY" https://api.example.com/users
Some APIs use basic authentication, which cURL makes even simpler with the -u flag:
curl -u username:password https://api.example.com/users
When to use it: This is your go-to command for smoke testing endpoints, verifying authentication is working correctly, or quickly checking what data an endpoint returns before writing your automated tests. It's also perfect for debugging when your test framework reports an authentication error. Run the same request with cURL to isolate whether the issue is with your credentials or your test code.
When you need to test creating resources or submitting data, POST requests with JSON payloads are essential. Here's the basic structure:
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"name": "John Doe", "email": "john@example.com"}'
The -X POST flag specifies the HTTP method, while -d (or --data) sends your payload. The Content-Type: application/json header is crucial because it tells the server how to interpret your data. Without it, many APIs will reject your request or misinterpret the payload.
For larger or more complex JSON payloads, you can reference an external file instead of inline data:
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d @user_data.json
The @ symbol tells cURL to read the data from a file, which keeps your command clean and makes it easier to maintain test data.
When to use it: Use POST requests to test resource creation workflows, validate request payload schemas, and verify that your API correctly handles valid and invalid data. This is particularly useful for exploratory testing before automating create/update/delete operations in your test suite. You can quickly iterate on different payload combinations to understand how the API behaves with edge cases, missing fields, or malformed data.
When an API call isn't behaving as expected, verbose mode is your debugging superpower. Add the -v flag to any cURL command to see the complete HTTP conversation:
curl -v https://api.example.com/users \
-H "Authorization: Bearer YOUR_TOKEN"
Verbose mode reveals everything: the complete request headers being sent (prefixed with >), the response headers received (prefixed with <), SSL handshake details, and any redirects that occur. This visibility is invaluable when you're trying to understand why a request is failing or behaving unexpectedly.
For example, you might discover that your authentication header isn't being sent correctly, that the server is returning a 301 redirect you weren't aware of, or that a required header is missing from your request. The output clearly separates request metadata, response metadata, and the actual response body, making it easy to pinpoint exactly where things go wrong.
When to use it: Reach for verbose mode whenever you encounter unexpected status codes, authentication failures, or responses that don't match your API documentation. It's especially helpful when debugging issues that only occur in certain environments, when comparing requests between your test framework and manual testing, or when you need to verify that SSL certificates are being validated correctly. Think of it as the equivalent of opening your browser's developer tools, but for command line API testing.
Response headers contain critical information that goes beyond the response body itself. To quickly check just the headers without downloading the full response, use the -I flag:
curl -I https://api.example.com/users
This sends a HEAD request and displays only the response headers, including status code, content type, cache directives, rate limit information, and custom API headers. It's fast and efficient when you only need to verify the metadata.
If you need both headers and the response body together, use the lowercase -i flag instead:
curl -i https://api.example.com/users \
-H "Authorization: Bearer YOUR_TOKEN"
This displays the complete response with headers at the top, followed by the body content. The headers and body are separated by a blank line, making it easy to distinguish between them.
Why headers matter in testing: Headers tell you far more than just whether a request succeeded. They reveal rate limiting information (like X-RateLimit-Remaining), caching behavior (Cache-Control, ETag), pagination details (Link headers), API versioning, and security policies (CORS headers, Content-Security-Policy). When testing APIs, you should verify not just that you get a 200 status code, but that the cache headers are set correctly for your use case, that rate limits are being communicated properly, and that security headers are present. Headers are often where you'll find clues about performance issues, unexpected caching, or misconfigured API gateways.
Performance matters in API testing, and cURL's -w (write-out) flag gives you precise timing metrics without needing external tools. Here's how to measure response time:
curl -w "\nTime Total: %{time_total}s\n" \
-o /dev/null -s \
https://api.example.com/users
The -w flag lets you format custom output with timing variables. The -o /dev/null sends the response body to nowhere (since you only care about timing), and -s silences the progress bar. You'll get a clean output showing exactly how long the request took.
For more comprehensive performance metrics, you can measure multiple timing phases:
curl -w "\nDNS Lookup: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS Handshake: %{time_appconnect}s\nTime to First Byte: %{time_starttransfer}s\nTotal Time: %{time_total}s\n" \
-o /dev/null -s \
https://api.example.com/users
This breaks down where time is being spent: DNS resolution, establishing the connection, SSL/TLS negotiation, waiting for the server to respond, and total request time.
You should also set timeouts to prevent hanging requests during testing:
curl --connect-timeout 5 --max-time 10 \
https://api.example.com/users
The --connect-timeout limits how long cURL waits to establish a connection, while --max-time sets the maximum time for the entire operation.
When to use it: Use timing metrics to establish performance baselines for your APIs, identify slow endpoints that need optimization, or verify that your APIs meet SLA requirements. Timeouts are essential in automated test suites to prevent a single slow or unresponsive endpoint from blocking your entire test run. Combine these techniques when load testing, comparing performance across different environments, or debugging intermittent slowness that only appears under certain conditions.
These five cURL commands give you a solid foundation for testing APIs quickly and effectively from the command line. The real power comes from combining these techniques and experimenting with different flags to match your specific testing scenarios. For a complete reference of cURL's capabilities, check out the official cURL documentation, and start incorporating these commands into your daily testing workflow. You'll be surprised how much faster you can validate API behavior before writing a single line of test automation code.