Quick Answer
Developers and system administrators rely on command-line utilities to inspect network paths, diagnose web server performance, and communicate directly with HTTP interfaces without opening a web browser. At the center of this toolkit is curl, a ubiquitous command-line tool for transferring data with URLs. Whether you are debugging microservice communications in a Kubernetes cluster or testing an external web service, curl bridges the gap between low-level networking protocols and high-level API engineering.
Understanding how to construct commands, interpret server responses, handle headers, and navigate network timeouts is essential for any modern software engineer. This guide breaks down the mechanics of network requests, explores protocol layers, and provides safe, copyable command patterns for your everyday development and production troubleshooting tasks.
Quick Answer
Image Pending
The underlying network lifecycle of a standard curl request.
What is curl? It is a command-line tool and library for transferring data using various network protocols, most notably HTTP and HTTPS. When you execute a standard command, the utility resolves the target hostname via DNS, establishes a TCP socket connection with the remote server, performs any required TLS handshakes, and transmits an HTTP request over the wire. It then receives the response from the server, printing the payload directly to your terminal standard output.
By operating directly in the terminal, engineers can script complex validation sequences, bypass graphical interface overhead, and inspect raw server responses with absolute precision. This makes it an indispensable asset when building robust APIs, validating webhook deliveries, or performing sanity checks on containerized cloud deployments.
Basic curl Requests
Making your first request requires only passing a URL to the command utility. By default, the tool performs an HTTP GET request, fetching the resource specified at the target address and displaying its body contents directly in your terminal window.
curl https://httpbin.org/get
When you run this command, the client connects to the remote host, requests the default endpoint, and outputs the resulting JSON payload. To save the output to a file rather than streaming it to your screen, you can use the -o flag:
curl -o response.json https://httpbin.org/get
Alternatively, using the -O flag saves the remote file using its original filename on the server. These basic execution patterns form the foundation for all subsequent network interactions, allowing you to quickly verify whether a web service is reachable from your current network interface.
GET/POST Methods
While GET requests retrieve data, web applications frequently require data submission via POST, PUT, or DELETE methods. To change the request method, you can use the -X flag paired with the desired HTTP verb, or supply data payloads which automatically trigger a POST request.
curl -X POST https://httpbin.org/post -d "name=devops&status=active"
When sending structured data like JSON payloads to modern APIs, you must also specify the correct content type header so the receiving server knows how to parse the incoming body stream:
curl -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-d '{"environment": "staging", "version": "1.2.0"}'
Using query parameters with GET requests is equally straightforward; simply append them directly to the URL string, ensuring you wrap the entire URL in quotes if it contains special characters like ampersands or spaces.
Inspect Response Headers
When debugging network applications, the response body tells only half the story. Server metadata, caching rules, security policies, and rate-limiting quotas are communicated entirely through response headers. By default, standard execution hides these headers to keep the terminal output clean.
To instruct the client to print response metadata alongside the body, use the -i or --include flag:
curl -i https://httpbin.org/headers
This command outputs the complete HTTP protocol version, response status code, and every header returned by the server before rendering the final body payload. This visibility is vital when investigating caching behavior, content-type mismatches, or unexpected proxy modifications.
headers
Analyzing specific response headers allows engineers to verify security postures, track proxy chains, and evaluate server configurations. For instance, you can check whether a content delivery network is actively caching your application assets by inspecting headers like CF-Cache-Status or Via.
curl -I https://example.com
Notice the capital -I flag in the command above. This triggers a HEAD request instead of a GET request, instructing the server to return only the response headers without any body content. This is exceptionally efficient when you need to check server availability or asset freshness over high-latency networks without downloading large payloads.
Send Request Headers
Just as servers send metadata back to clients, applications often require specific request headers to function correctly. Authorization tokens, API keys, custom user agents, and content negotiation directives are all transmitted via custom request headers.
To pass a custom header, use the -H or --header flag. You can include multiple headers in a single command by repeating the flag:
curl -H "Authorization: Bearer secret_token_123" \
-H "Accept: application/vnd.api+json" \
https://api.example.com/v1/resource
This capability is essential when interacting with secure microservices, authenticating against cloud provider APIs, or testing how an endpoint behaves when receiving specific content types from downstream clients.
Test APIs
Connecting network diagnostics to real developer workflows means validating end-to-end API behavior. When building and deploying web services, engineers must verify that routes return the correct data structures, handle malformed inputs gracefully, and respond with appropriate HTTP status codes.
curl -s -X GET https://api.github.com/zen
The -s or --silent flag suppresses the progress meter and error messages, ensuring that only the raw response is piped into downstream utilities or automation scripts. Combining silent mode with JSON processors like jq allows for clean, automated endpoint validation in CI/CD pipelines.
status codes
HTTP status codes are the primary mechanism by which servers communicate the outcome of a request. Understanding these codes is critical for effective API troubleshooting. Below is a breakdown of standard status categories encountered during command-line testing:
When an endpoint returns a 401 Unauthorized or 403 Forbidden, you immediately know your request headers or credentials require adjustment. Conversely, a 502 Bad Gateway points toward infrastructure or reverse-proxy routing issues rather than application logic errors.
Follow Redirects and Timeouts
Web architectures frequently employ URL redirection, moving resources from HTTP to HTTPS or shifting traffic across domain names. By default, the client does not automatically follow redirection responses like 301 or 302.
To instruct the tool to automatically chase redirection chains until it reaches the final destination resource, use the -L or --location flag:
curl -L https://httpbin.org/redirect/1
Combined with timeout configurations, this ensures your scripts do not hang indefinitely when network partitions or unresponsive upstream services occur.
verbose mode
Image Pending
Verbose mode exposes every detail of the network handshake and protocol exchange.
When basic requests fail and headers alone are not enough to diagnose the issue, you need complete visibility into the underlying transport layer. Verbose mode opens a window into the exact dialogue taking place between your local machine and the remote server.
curl -v https://httpbin.org/get
Executing this command outputs detailed diagnostic information prefixed with descriptive symbols:
*indicates informational connection details, DNS resolution, and TLS handshakes.>displays outbound request headers sent by your client.<displays inbound response headers received from the server.
This granular view is indispensable when debugging cipher suite mismatches, expired SSL certificates, or unexpected proxy header injections.
timeouts
Network environments are unpredictable, and unresponsive servers can cause automation scripts to hang indefinitely. Setting explicit timeouts prevents your testing pipelines from locking up when services fail to respond.
curl --connect-timeout 5 --max-time 15 https://api.example.com/data
--connect-timeout 5limits the time allowed for the initial TCP connection and TLS handshake to complete, failing fast if the server is unreachable.--max-time 15limits the total operation duration, ensuring the entire request-response cycle wraps up within fifteen seconds.
Troubleshoot Connectivity
Effective network troubleshooting requires a systematic, layer-by-layer verification approach. A common developer mistake is treating DNS resolution, TCP connectivity, and HTTP application logic as a single monolithic block. When an API call fails, isolating the exact point of failure prevents wasted time.
Consider a realistic troubleshooting scenario where an engineer attempts to reach an internal microservice and receives a connection timeout:
- Verify DNS resolution using basic name lookup tools to confirm the hostname resolves to the expected IP address.
- Test raw TCP socket connectivity to verify that firewalls or security groups permit traffic on the target port.
- Execute a verbose request to inspect whether the TLS handshake succeeds or stalls.
curl -v https://internal-service.local/health
By following this layered methodology, you quickly determine whether the root cause is a misconfigured DNS record, a blocked security group port, or an unresponsive application process.
Safe Examples
Running diagnostic commands in production environments requires strict adherence to security best practices. Never pass sensitive credentials, API secrets, or private keys directly in command-line arguments where they can be captured in shell history files or process inspection tables.
Instead, store secrets in secure environment variables or configuration files, referencing them safely within your commands:
curl -H "Authorization: Bearer $API_SECRET_TOKEN" https://api.example.com/v1/secure
Furthermore, avoid disabling TLS verification flags (such as -k or --insecure) as a routine troubleshooting shortcut. Bypassing certificate validation exposes your workflows to man-in-the-middle attacks and masks underlying trust chain misconfigurations. Always verify commands against current authoritative documentation and maintain strict hygiene when interacting with production cloud infrastructure.