| name | api-request |
| category | web |
| description | Send HTTP API requests using curl. Use when the user asks to call an API, fetch data from a URL, send POST/PUT/PATCH/DELETE requests, work with REST or GraphQL endpoints, upload files, authenticate with Bearer tokens or API keys, debug HTTP responses, or interact with any web service via HTTP.
|
| license | MIT |
| compatibility | Requires curl (pre-installed on macOS and most Linux distributions) |
| metadata | {"author":"zeph","version":"1.0"} |
HTTP API Requests with curl
Quick Reference
| Action | Command |
|---|
| GET | curl -s URL |
| POST JSON | curl -s -X POST -H "Content-Type: application/json" -d '{}' URL |
| PUT | curl -s -X PUT -H "Content-Type: application/json" -d '{}' URL |
| PATCH | curl -s -X PATCH -H "Content-Type: application/json" -d '{}' URL |
| DELETE | curl -s -X DELETE URL |
| HEAD | curl -s -I URL |
Essential Options
| Option | Long form | Purpose |
|---|
-s | --silent | Suppress progress bar (always use for scripting) |
-S | --show-error | Show errors even when silent |
-X | --request | HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) |
-H | --header | Add request header (-H "Name: Value") |
-d | --data | Send request body (implies POST) |
-o | --output | Write response body to file |
-w | --write-out | Print metadata after transfer (status code, timing) |
-L | --location | Follow HTTP redirects (3xx) |
-i | --include | Include response headers in output |
-I | --head | Fetch headers only (HEAD request) |
-k | --insecure | Skip TLS certificate verification |
-v | --verbose | Show full request/response exchange for debugging |
-f | --fail | Return exit code 22 on HTTP errors (4xx/5xx) |
-F | --form | Multipart form field (implies POST, multipart/form-data) |
-u | --user | Basic auth credentials (user:password) |
Timeouts
curl -s --connect-timeout 10 URL
curl -s --max-time 30 URL
curl -sS --connect-timeout 10 --max-time 30 URL
GET Requests
curl -s "https://api.example.com/users"
curl -s "https://api.example.com/users?status=active&limit=10"
curl -sL "https://example.com/redirect"
curl -sS -o response.json "https://api.example.com/data"
POST Requests
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@example.com"}' \
"https://api.example.com/users"
curl -s -X POST \
-H "Content-Type: application/json" \
-d @payload.json \
"https://api.example.com/users"
curl -s -X POST \
-d "username=alice&password=secret" \
"https://api.example.com/login"
curl -s -X POST "https://api.example.com/trigger"
PUT and PATCH
curl -s -X PUT \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@new.com", "role": "admin"}' \
"https://api.example.com/users/42"
curl -s -X PATCH \
-H "Content-Type: application/json" \
-d '{"email": "alice@new.com"}' \
"https://api.example.com/users/42"
DELETE
curl -s -X DELETE "https://api.example.com/users/42"
curl -s -X DELETE \
-H "Content-Type: application/json" \
-d '{"reason": "duplicate"}' \
"https://api.example.com/users/42"
Authentication
curl -s -H "Authorization: Bearer eyJhbGciOi..." "https://api.example.com/me"
curl -s -H "X-API-Key: abc123" "https://api.example.com/data"
curl -s "https://api.example.com/data?api_key=abc123"
curl -s -u "admin:secret" "https://api.example.com/admin"
curl -s -u "admin" "https://api.example.com/admin"
File Upload
curl -s -F "file=@/path/to/document.pdf" "https://api.example.com/upload"
curl -s -F "file=@photo.jpg;type=image/jpeg" "https://api.example.com/upload"
curl -s \
-F "file=@report.pdf" \
-F "title=Q4 Report" \
-F "category=finance" \
"https://api.example.com/documents"
curl -s \
-F "files=@file1.txt" \
-F "files=@file2.txt" \
"https://api.example.com/batch-upload"
curl -s -X PUT \
-H "Content-Type: application/octet-stream" \
--data-binary @image.png \
"https://api.example.com/files/image.png"
Response Handling
curl -s -o /dev/null -w "%{http_code}" "https://api.example.com/health"
curl -s -w "\n%{http_code}" "https://api.example.com/users"
curl -si "https://api.example.com/users"
curl -s -o /dev/null -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\nStatus: %{http_code}\n" "https://api.example.com"
curl -s "https://api.example.com/users" | jq .
curl -s "https://api.example.com/users/1" | jq -r '.email'
curl -sI "https://api.example.com/users"
Common Patterns
Pagination
curl -s "https://api.example.com/items?offset=0&limit=50"
curl -s "https://api.example.com/items?offset=50&limit=50"
curl -s "https://api.example.com/items?page=1&per_page=25"
curl -s "https://api.example.com/items?cursor=eyJpZCI6MTAwfQ"
Retry on Failure
curl -s --retry 3 --retry-delay 2 --retry-max-time 30 "https://api.example.com/data"
curl -s --retry 3 --retry-all-errors "https://api.example.com/data"
Conditional Requests
curl -s -H "If-Modified-Since: Mon, 01 Jan 2024 00:00:00 GMT" "https://api.example.com/data"
curl -s -H 'If-None-Match: "abc123"' "https://api.example.com/data"
GraphQL
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"query": "{ users(first: 10) { id name email } }"}' \
"https://api.example.com/graphql"
Debugging
curl -v "https://api.example.com/users" 2>&1
curl --trace trace.log "https://api.example.com/users"
curl -sI "https://api.example.com/users"
curl -sS -D headers.txt -o body.json "https://api.example.com/users"
HTTP Status Code Reference
| Range | Meaning | Common Codes |
|---|
| 2xx | Success | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirect | 301 Moved, 302 Found, 304 Not Modified |
| 4xx | Client error | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable, 429 Too Many Requests |
| 5xx | Server error | 500 Internal Error, 502 Bad Gateway, 503 Unavailable, 504 Timeout |
Important Notes
- Always use
-s (silent) to suppress the progress bar in scripts
- Use
-sS to suppress progress but still show errors
- When sending JSON, always set
-H "Content-Type: application/json"
- Use
-L to follow redirects (curl does not follow them by default)
- Use
--connect-timeout and --max-time for robustness against hanging requests
- Pipe to
jq . for readable JSON output, or jq -r '.field' to extract values
- Use
-f (fail) when you need curl to return a non-zero exit code on HTTP errors
- For binary data in POST body, use
--data-binary instead of -d (which strips newlines)
- Special characters in URLs should be percent-encoded (spaces =
%20, & = %26)
- Use single quotes around JSON payloads to avoid shell variable expansion issues