Skip to main content

api-request

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.

Source facts

Repository
bug-ops/zeph
Last source activity
March 30, 2026 at 00:01
Detected SKILL.md language
English
Stars
65
Forks
7

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
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 ```bash # Connection timeout (seconds to establish TCP connection) curl -s --connect-timeout 10 URL # Max total time (entire operation including transfer) curl -s --max-time 30 URL # Both together (recommended for robustness) curl -sS --connect-timeout 10 --max-time 30 URL ``` ## GET Requests ```bash # Simple GET curl -s "https://api.example.com/users" # With query parameters (URL-encode special characters) curl -s "https://api.example.com/users?status=active&limit=10" # Follow redirects curl -sL "https://example.com/redirect" # Save response to file curl -sS -o response.json "https://api.example.com/data" ``` ## POST Requests ```bash # JSON body (most common for REST APIs) curl -s -X POST \ -H "Content-Type: application/json" \ -d '{"name": "Alice", "email": "alice@example.com"}' \ "https://api.example.com/users" # JSON body from file curl -s -X POST \ -H "Content-Type: application/json" \ -d @payload.json \ "https://api.example.com/users" # URL-encoded form data curl -s -X POST \ -d "username=alice&password=secret" \ "https://api.example.com/login" # Empty POST (some APIs require POST with no body) curl -s -X POST "https://api.example.com/trigger" ``` ## PUT and PATCH ```bash # PUT — full resource replacement curl -s -X PUT \ -H "Content-Type: application/json" \ -d '{"name": "Alice", "email": "alice@new.com", "role": "admin"}' \ "https://api.example.com/users/42" # PATCH — partial update curl -s -X PATCH \ -H "Content-Type: application/json" \ -d '{"email": "alice@new.com"}' \ "https://api.example.com/users/42" ``` ## DELETE ```bash # Simple DELETE curl -s -X DELETE "https://api.example.com/users/42" # DELETE with body (some APIs require it) curl -s -X DELETE \ -H "Content-Type: application/json" \ -d '{"reason": "duplicate"}' \ "https://api.example.com/users/42" ``` ## Authentication ```bash # Bearer token (OAuth2, JWT) curl -s -H "Authorization: Bearer eyJhbGciOi..." "https://api.example.com/me" # API key in header curl -s -H "X-API-Key: abc123" "https://api.example.com/data" # API key as query parameter curl -s "https://api.example.com/data?api_key=abc123" # Basic auth (user:password) curl -s -u "admin:secret" "https://api.example.com/admin" # Basic auth with prompt for password (interactive) curl -s -u "admin" "https://api.example.com/admin" ``` ## File Upload ```bash # Single file upload (multipart/form-data) curl -s -F "file=@/path/to/document.pdf" "https://api.example.com/upload" # File with explicit content type curl -s -F "file=@photo.jpg;type=image/jpeg" "https://api.example.com/upload" # File with additional form fields curl -s \ -F "file=@report.pdf" \ -F "title=Q4 Report" \ -F "category=finance" \ "https://api.example.com/documents" # Multiple files curl -s \ -F "files=@file1.txt" \ -F "files=@file2.txt" \ "https://api.example.com/batch-upload" # Raw binary upload (PUT) curl -s -X PUT \ -H "Content-Type: application/octet-stream" \ --data-binary @image.png \ "https://api.example.com/files/image.png" ``` ## Response Handling ```bash # Get HTTP status code only curl -s -o /dev/null -w "%{http_code}" "https://api.example.com/health" # Get status code + response body curl -s -w "\n%{http_code}" "https://api.example.com/users" # Get response headers + body curl -si "https://api.example.com/users" # Detailed timing info 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" # Pretty-print JSON response (pipe to jq) curl -s "https://api.example.com/users" | jq . # Extract specific field from JSON curl -s "https://api.example.com/users/1" | jq -r '.email' # Response headers only curl -sI "https://api.example.com/users" ``` ## Common Patterns ### Pagination ```bash # Offset-based curl -s "https://api.example.com/items?offset=0&limit=50" curl -s "https://api.example.com/items?offset=50&limit=50" # Page-based curl -s "https://api.example.com/items?page=1&per_page=25" # Cursor-based (use cursor from previous response) curl -s "https://api.example.com/items?cursor=eyJpZCI6MTAwfQ" ``` ### Retry on Failure ```bash # Retry up to 3 times with exponential backoff curl -s --retry 3 --retry-delay 2 --retry-max-time 30 "https://api.example.com/data" # Retry only on specific errors (transient) curl -s --retry 3 --retry-all-errors "https://api.example.com/data" ``` ### Conditional Requests ```bash # If-Modified-Since (returns 304 if unchanged) curl -s -H "If-Modified-Since: Mon, 01 Jan 2024 00:00:00 GMT" "https://api.example.com/data" # ETag-based caching curl -s -H 'If-None-Match: "abc123"' "https://api.example.com/data" ``` ### GraphQL ```bash curl -s -X POST \ -H "Content-Type: application/json" \ -d '{"query": "{ users(first: 10) { id name email } }"}' \ "https://api.example.com/graphql" ``` ## Debugging ```bash # Verbose output (shows full request/response headers and TLS handshake) curl -v "https://api.example.com/users" 2>&1 # Trace to file (hex dump of all data) curl --trace trace.log "https://api.example.com/users" # Show only response headers curl -sI "https://api.example.com/users" # Dump request and response headers to file 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
View on GitHub