Test a JSON API with curl
A runnable bash script showing the curl commands you need most when testing an API: GET, POST JSON, custom headers, Bearer tokens, -i, -v, and status codes.
curl is a command-line tool that sends HTTP requests and prints the response. It ships with macOS, most Linux distributions, and Windows 10 and later, which makes it the quickest way to poke at an API without writing any code.
The script
Save this as api-check.sh, make it executable with chmod +x api-check.sh, and pass the base URL of the API you want to test. It defaults to a local test server on port 8765.
#!/usr/bin/env bash
# Try the most common curl calls against a JSON API.
# Usage: ./api-check.sh [BASE_URL]
set -euo pipefail
BASE_URL="${1:-http://127.0.0.1:8765}"
TOKEN="${API_TOKEN:-replace-me-with-a-test-token}"
echo "== 1. Simple GET (body only)"
curl -sS "$BASE_URL/items?limit=2"
echo
echo "== 2. GET with status line and response headers (-i)"
curl -sS -i "$BASE_URL/items/1"
echo
echo "== 3. POST JSON (--json sets Content-Type and Accept for you)"
curl -sS --json '{"name": "notebook", "price": 4.5}' "$BASE_URL/items"
echo
echo "== 4. Same POST, spelled out by hand"
curl -sS -X POST "$BASE_URL/items" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name": "pencil", "price": 0.8}'
echo
echo "== 5. Authenticated request with a Bearer token"
curl -sS -H "Authorization: Bearer $TOKEN" "$BASE_URL/me"
echo
echo "== 6. Only the status code (handy in scripts)"
code=$(curl -sS -o /dev/null -w '%{http_code}' "$BASE_URL/status/404")
echo "status: $code"
echo "== 7. --fail makes curl exit non-zero on 4xx/5xx"
if curl -sS --fail -o /dev/null "$BASE_URL/status/500"; then
echo "request succeeded"
else
echo "request failed with exit code $?"
fi
echo "== 8. Verbose: see the request curl sends (lines starting with >)"
curl -sS -v -o /dev/null "$BASE_URL/items" 2>&1 | grep -E '^[<>] ' | head -n 12
What the flags mean
-ssilences the progress bar;-Sstill shows errors.-iincludes the status line and response headers in the output.-v(verbose) also shows what curl sends. Lines starting with>are the request,<the response. It writes to stderr, so use2>&1to pipe it.-H 'Name: value'adds a request header. Repeat it for more headers.-dsends a request body and switches the method to POST. Add-X PUTor-X PATCHfor other methods.--json(curl 7.82 and newer) sends a body and sets bothContent-TypeandAccepttoapplication/json.-o /dev/null -w '%{http_code}'throws the body away and prints just the status code.--failmakes curl exit with code 22 on HTTP errors, which is what you want in CI scripts.-Lfollows redirects, which curl does not do by default.
A practice server
Want something safe to test against? The companion entry Tiny JSON echo server for testing HTTP clients runs on 127.0.0.1:8765 and replies with exactly what it received, so you can see your headers and body arrive.
Tips
- Quote JSON bodies with single quotes in bash so the double quotes inside survive. On Windows
cmd.exe, put the body in a file and use-d @body.jsoninstead. - Keep tokens in environment variables (
export API_TOKEN=...), not in the script, and never commit them. - Pipe JSON output into
jq(if you have it) orpython3 -m json.toolto pretty-print it.
See also
- 0019 fetch with timeout, retries and proper error handling A reusable fetchJson helper for Node 20+ and browsers that adds a timeout, retries with backoff for temporary failures, and clear errors… Intermediate · How-to · Any system Script Async code · Making requests 15 Oct 2026
- 0081 How an HTTP request works: methods, headers, and body An HTTP request is a short text message a client sends to a server: a method and path, some headers, and sometimes… Beginner · Concept · Any system Article Making requests 15 Oct 2026
- 0084 Tiny JSON echo server for testing HTTP clients A standard-library Python server that echoes back the method, path, query, headers, and body of every request, and can return any status… Intermediate · How-to · Any system Script Files & automation · Making requests 15 Oct 2026
- 0085 fetch with timeout, retries, and exponential backoff A drop-in fetch wrapper that times out slow requests, retries network errors and 429/5xx responses with jittered exponential backoff, and honors Retry-After. Advanced · How-to · Any system, Browser Script Async code · Making requests 15 Oct 2026
- 0086 API authentication basics: API keys, Bearer tokens, and OAuth How APIs know who is calling: static API keys, Bearer tokens in the Authorization header, Basic auth, and a high-level tour of… Intermediate · Concept · Any system Article Authentication 15 Oct 2026
- 0087 CORS explained: why the browser blocks your request CORS is the browser rule that decides whether JavaScript on one origin may read a response from another. The server opts in… Intermediate · Concept · Browser Article Async code · Making requests 15 Oct 2026
Repos in the wild
- Requests: HTTP for humans psf/requests Requests is the classic Python library for calling web APIs and downloading pages, with a simple API for GET and POST requests, headers, JSON and sessions. GitHub
- Axios axios/axios A promise-based HTTP client for browsers and Node.js with interceptors, automatic JSON handling, request cancellation and a consistent API in both environments. GitHub
- curl and libcurl (curl/curl) curl/curl The source of curl, the command-line tool for transferring data with URLs, and libcurl, the C library behind it that many other programs use for HTTP. GitHub
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- commitpedia-admin +3,534 chars