How to Use cURL to Test APIs — Commands, Examples & Convert to Code
cURL is the fastest way to test an API without writing any code. One command in your terminal — you see the raw HTTP response, status code, headers, and body instantly. This guide covers every cURL pattern developers use daily: GET, POST with JSON, auth headers, PUT/PATCH/DELETE, debugging flags, and how to convert any cURL command into Python or JavaScript code for your application.
30+ years
cURL has been the standard for HTTP testing since 1997
zero setup
Pre-installed on macOS, Linux — available on Windows via WSL or Git Bash
1 command
Test any REST API endpoint — no Postman, no browser, no code
What Is cURL and Why Do Developers Use It?
cURL (Client URL) is a command-line tool for making HTTP requests. It is pre-installed on macOS and every major Linux distribution. On Windows, it is included in Git Bash, WSL, and Windows 10+ natively. Developers use it to:
Test API endpoints instantly
Check if an endpoint returns the right data, status code, and headers without writing any code or opening a browser.
Debug authentication issues
Test whether a Bearer token, API key, or session cookie is valid by making a raw authenticated request and seeing exactly what comes back.
Reproduce production requests
Chrome DevTools lets you copy any browser network request as cURL. Paste it into your terminal to reproduce the exact request the browser made.
Test edge cases quickly
Try different request bodies, headers, and query parameters without modifying code. Faster than writing a test for every variation.
Share reproducible examples
cURL commands are the universal format for API issue reports, Stack Overflow questions, and documentation. Everyone can run them.
Script API calls in CI/CD
cURL in shell scripts calls webhooks, checks health endpoints, deploys artifacts, and tests APIs as part of automated pipelines.
Already have a cURL command? Convert it to code instantly
Basic cURL GET Request
The simplest cURL command — just the URL. cURL defaults to GET when no method is specified.
# Basic GET — returns the response body
curl https://api.example.com/users
# GET with pretty-printed JSON output (pipe through python -m json.tool)
curl https://api.example.com/users | python3 -m json.tool
# GET and see response headers too (-i = include headers)
curl -i https://api.example.com/users
# GET and see ONLY the response headers (-I = HEAD request)
curl -I https://api.example.com/users
# GET and save the output to a file (-o = output file)
curl https://api.example.com/users -o users.json
# GET with verbose output — see the full request and response (-v)
curl -v https://api.example.com/users-i (include response headers)
Shows both the response headers AND the body. Use this to inspect status codes, Content-Type, Cache-Control, and any custom headers the server returns.
-v (verbose)
Shows the full request (headers cURL sends) AND the full response (headers the server returns) plus TLS handshake details. Essential for debugging connection issues.
-o filename (save output)
Saves the response body to a file instead of printing to stdout. Use -O (capital O) to save with the filename from the URL path.
-s (silent)
Suppresses the progress meter and error messages. Use in scripts so the output is only the response body — no noise.
cURL POST with JSON Body
Posting JSON to an API requires two things: the -d flag with the JSON string, and the Content-Type: application/json header. Missing the Content-Type is one of the most common bugs when using cURL with REST APIs.
cURL POST with JSON — missing Content-Type vs. correct
Missing Content-Type — API rejects the request
# Wrong: API receives the body but treats it as text, not JSON
curl -X POST 'https://api.example.com/users' -d '{"name": "Alice", "email": "alice@example.com"}'
# → 400 Bad Request or 415 Unsupported Media TypeCorrect — API receives and parses JSON
# Correct: always include Content-Type: application/json with JSON bodies
curl -X POST 'https://api.example.com/users' -H 'Content-Type: application/json' -d '{"name": "Alice", "email": "alice@example.com"}'
# → 201 Created# POST with inline JSON body
curl -X POST 'https://api.example.com/users' -H 'Content-Type: application/json' -H 'Authorization: Bearer TOKEN' -d '{"name": "Alice", "email": "alice@example.com", "role": "admin"}'
# POST with JSON from a file (@ prefix reads from file)
curl -X POST 'https://api.example.com/users' -H 'Content-Type: application/json' -H 'Authorization: Bearer TOKEN' -d @user-payload.json
# POST with URL-encoded form data (like an HTML form submission)
curl -X POST 'https://api.example.com/login' -d 'username=alice&password=s3cr3t'
# POST with multipart form data (file upload)
curl -X POST 'https://api.example.com/upload' -H 'Authorization: Bearer TOKEN' -F 'file=@/path/to/document.pdf' -F 'title=Q4 Report'--data vs --data-raw vs --data-binary
-d (or --data) URL-encodes the data and strips newlines. Use --data-raw when the data contains @ characters you do not want interpreted as filenames. Use --data-binary to send binary data or preserve newlines — critical when sending JSON read from a file that contains newlines.
cURL with Authentication — Bearer Token, Basic Auth, API Key
Most APIs require authentication. cURL supports all common auth patterns with the -H flag for header-based auth or -u for HTTP Basic auth.
# Bearer token (most common — OAuth 2.0, JWT)
curl 'https://api.example.com/me' -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'
# HTTP Basic auth — username:password
curl 'https://api.example.com/data' -u 'myuser:mypassword'
# cURL auto-encodes as Base64 and sets Authorization: Basic header
# API key in a header (varies by API — check the docs)
curl 'https://api.example.com/data' -H 'X-API-Key: sk-live-abc123'
# API key in a query string
curl 'https://api.example.com/data?api_key=sk-live-abc123'
# GitHub API example (token in header)
curl 'https://api.github.com/user/repos' -H 'Authorization: token ghp_yourtoken' -H 'Accept: application/vnd.github.v3+json'
# OpenAI API example
curl 'https://api.openai.com/v1/models' -H 'Authorization: Bearer sk-proj-...'Never put tokens in URLs in production
?api_key=TOKEN) appear in server logs, browser history, referrer headers, and intermediary proxies. Always use the Authorization header for auth tokens in production. Query string auth is only acceptable for short-lived, low-privilege tokens in specific contexts.cURL PUT, PATCH, DELETE — Full CRUD
BASE='https://api.example.com'
TOKEN='Bearer TOKEN'
# READ — GET a single resource
curl "$BASE/users/42" -H "Authorization: $TOKEN"
# CREATE — POST a new resource
curl -X POST "$BASE/users" -H "Content-Type: application/json" -H "Authorization: $TOKEN" -d '{"name": "Bob", "email": "bob@example.com"}'
# FULL UPDATE — PUT replaces the entire resource
curl -X PUT "$BASE/users/42" -H "Content-Type: application/json" -H "Authorization: $TOKEN" -d '{"name": "Bob Smith", "email": "bob@example.com", "role": "viewer"}'
# PARTIAL UPDATE — PATCH updates only specified fields
curl -X PATCH "$BASE/users/42" -H "Content-Type: application/json" -H "Authorization: $TOKEN" -d '{"role": "admin"}'
# DELETE
curl -X DELETE "$BASE/users/42" -H "Authorization: $TOKEN"
# Returns 204 No Content on successUseful cURL Debugging Flags
These flags help diagnose connection issues, TLS problems, redirects, and slow requests. Invaluable when an API call works in the browser but fails from your script.
# -v (verbose) — see the full request, response headers, TLS handshake
curl -v 'https://api.example.com/data'
# -w (write-out) — time the request breakdown
curl -w "
DNS: %{time_namelookup}s
Connect: %{time_connect}s
TLS: %{time_appconnect}s
Total: %{time_total}s
" -o /dev/null -s 'https://api.example.com/data'
# -L (follow redirects) — follow 301/302 automatically
curl -L 'https://api.example.com/old-path'
# -k (insecure) — skip SSL cert validation (dev/testing only, never production)
curl -k 'https://localhost:8443/api'
# --retry 3 — retry on connection failure
curl --retry 3 --retry-delay 2 'https://api.example.com/data'
# --limit-rate 100k — throttle download speed (useful for testing)
curl --limit-rate 100k 'https://api.example.com/large-file.json'
# -x (proxy) — route through a proxy server
curl -x 'http://proxy.internal:8080' 'https://api.example.com/data'
# --resolve — test with a specific IP (bypass DNS for one request)
curl --resolve 'api.example.com:443:192.168.1.100' 'https://api.example.com/data'From cURL to Production Code — Convert in One Paste
Once you have validated an API call with cURL, the next step is getting it into your application. Rather than translating the command by hand, paste it into the online converter for clean, working code in seconds.
Validate the request with cURL first
Run the cURL command in your terminal and confirm you get the expected response. Fix auth, headers, and payload issues at the cURL level — it is much faster than debugging application code.
Pick your target language
For Python scripts, data pipelines, and automation: use the cURL → Python converter. For React, Vue, Node.js backend, or serverless functions: use the cURL → JavaScript converter (fetch or Axios).
Paste the cURL and copy the code
Go to unblockdevs.com/curl-to-python or unblockdevs.com/curl-converter. Paste the cURL command. The tool parses all flags — URL, headers, body, auth, method — and generates idiomatic code for your chosen language.
Add error handling and use in production
The generated code includes the request structure. Add try/except (Python) or try/catch (JavaScript), handle specific status codes, and wrap it in your service layer. The hard part — getting the request right — is already done.
Pro workflow: Chrome DevTools → cURL → Python or JavaScript