From cURL to Code: Converting API Commands to Any Language
cURL is the universal language of HTTP. API documentation almost always includes cURL examples, and browser DevTools let you copy any request as cURL. But when it comes time to write actual application code, you need that cURL command in JavaScript, Python, Go, or whatever your project uses. This guide breaks down cURL syntax and shows how it maps to code.
Anatomy of a cURL command
Every cURL command has the same basic structure:
curl [options] [URL]
Here is a realistic example with the most common flags:
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGci..." \
-d '{"name": "Alice", "email": "alice@example.com"}'
Let's break down each flag.
-X (request method)
Specifies the HTTP method. Without -X, cURL defaults to GET. When you use -d (data), it automatically switches to POST, so -X POST is technically redundant with -d but adds clarity.
curl -X GET https://api.example.com/users # Explicit GET
curl -X PUT https://api.example.com/users/1 # Update
curl -X DELETE https://api.example.com/users/1 # Delete
curl -X PATCH https://api.example.com/users/1 # Partial update
-H (header)
Adds an HTTP header. You can include multiple -H flags. The most common headers are Content-Type, Authorization, and Accept.
curl https://api.example.com/data \
-H "Accept: application/json" \
-H "Authorization: Bearer token123" \
-H "X-Request-ID: abc-def-ghi"
-d (data / request body)
Sends data in the request body. By default, the content type is application/x-www-form-urlencoded. For JSON, you need to explicitly set the Content-Type header.
# JSON body
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "Alice"}'
# Form data
curl -X POST https://api.example.com/login \
-d "username=alice&password=secret"
# Read body from file
curl -X POST https://api.example.com/upload \
-H "Content-Type: application/json" \
-d @payload.json
-u (basic auth)
Shorthand for HTTP Basic Authentication. cURL Base64-encodes the credentials and adds the Authorization: Basic ... header.
curl -u username:password https://api.example.com/protected
# Equivalent to:
curl -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" https://api.example.com/protected
Other useful flags
-v # Verbose output (see request/response headers)
-s # Silent mode (no progress bar)
-o file # Save response to file
-L # Follow redirects
-k # Skip SSL verification (development only)
-i # Include response headers in output
--data-raw # Send data without processing @ signs
Converting to JavaScript (fetch)
The cURL example from above translates directly to the Fetch API:
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer eyJhbGci...',
},
body: JSON.stringify({
name: 'Alice',
email: 'alice@example.com',
}),
});
const data = await response.json();
Key differences: fetch does not throw on HTTP errors (4xx/5xx), so you need to check response.ok. The body must be a string, not an object.
Converting to JavaScript (axios)
Axios has a slightly different API that handles JSON serialization automatically:
const { data } = await axios.post('https://api.example.com/users', {
name: 'Alice',
email: 'alice@example.com',
}, {
headers: {
'Authorization': 'Bearer eyJhbGci...',
},
});
Axios automatically sets Content-Type: application/json when you pass an object as the body, and it throws on non-2xx status codes.
Converting to Python (requests)
Python's requests library maps almost 1:1 with cURL:
import requests
response = requests.post(
'https://api.example.com/users',
json={'name': 'Alice', 'email': 'alice@example.com'},
headers={'Authorization': 'Bearer eyJhbGci...'},
)
data = response.json()
Using the json parameter instead of data automatically sets the Content-Type header and serializes the dictionary.
Converting to Go
Go requires more boilerplate but gives you full control:
body := bytes.NewBuffer([]byte(`{"name":"Alice","email":"alice@example.com"}`))
req, err := http.NewRequest("POST", "https://api.example.com/users", body)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer eyJhbGci...")
client := &http.Client{}
resp, err := client.Do(req)
defer resp.Body.Close()
Debugging tricks with cURL
See the full request and response
curl -v https://api.example.com/health
The -v flag shows the TLS handshake, request headers, response headers, and body. Lines starting with > are sent, lines starting with < are received.
Time the request
curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n" https://api.example.com/health
This shows you where time is being spent: DNS resolution, TCP connect, TLS handshake, or server processing.
Copy as cURL from browser DevTools
In Chrome or Firefox DevTools, right-click any network request and select "Copy as cURL." This gives you an exact reproduction of the request including cookies, headers, and body. It is the fastest way to debug API issues outside the browser.
Test with different methods
# Check if an endpoint exists without downloading the body
curl -I https://api.example.com/large-file
# Send an empty POST (useful for trigger endpoints)
curl -X POST https://api.example.com/webhook
Common gotchas
Single vs double quotes on Windows. Windows Command Prompt does not support single quotes. Use double quotes and escape inner quotes: curl -d "{\"name\":\"Alice\"}".
Forgetting Content-Type. Sending a JSON body without Content-Type: application/json causes many APIs to reject the request with a 415 Unsupported Media Type error.
URL encoding. Special characters in query parameters need URL encoding. Use --data-urlencode for form data or encode manually for URLs.
Summary
cURL is the lingua franca of HTTP APIs. Understanding its flags -- especially -X, -H, -d, and -u -- lets you read any API documentation and translate it to your language of choice. The mapping is mechanical: method, URL, headers, and body are the same concepts in every HTTP library.
Try our cURL Converter to convert any cURL command to fetch, axios, Python, and more instantly -- right in your browser, no upload required.