Most modern APIs speak JSON with token auth; this is the everyday curl workflow.
For JSON APIs, use --json (curl 7.82+). It sends the data as the body, sets Content-Type: application/json and Accept: application/json, and uses POST:
curl --json '{"name":"Ann"}' https://api.example.com/users
--json @user.json reads a file and --json @- reads stdin, so you can pipe generated JSON in. Combine with -X PATCH or -X PUT for other methods. On older curl, the equivalent is -H 'Content-Type: application/json' -d '{...}'.
Building JSON by hand in shell quotes gets messy quickly; generate it with jq -n --arg name "$NAME" '{name: $name}' and pipe it into --json @- so quoting and escaping are always right.
Authentication:
- Bearer tokens:
-H "Authorization: Bearer $TOKEN"(or--oauth2-bearer "$TOKEN"). - Basic auth:
-u user:password, which curl base64-encodes into anAuthorization: Basicheader.-u useralone prompts for the password, keeping it out of shell history. - API keys usually go in a custom header such as
-H "X-API-Key: $KEY".
Keep secrets in environment variables or files, not literally in commands: anything on the command line can end up in shell history and is visible to other users in ps. Then pipe the response into jq to read it: curl -sS ... | jq '.items[].name'.
Example
curl --json '{"name":"Ann","role":"admin"}' https://api.example.com/users
# sends POST, Content-Type and Accept: application/json
jq -n --arg name "$NAME" '{name: $name}' | curl --json @- https://api.example.com/users
curl -X PATCH --json '{"role":"viewer"}' https://api.example.com/users/42
curl -sS -H "Authorization: Bearer $API_TOKEN" https://api.example.com/me | jq .email
curl -u ann https://intranet.example.com/report # prompts for password
curl -sS -H "X-API-Key: $KEY" 'https://api.example.com/items?limit=2' | jq '.items[].name'Remember
- --json sets body, Content-Type and Accept in one flag
- Bearer: -H "Authorization: Bearer $TOKEN"; basic: -u user
- Generate JSON with jq and pipe it to --json @-
Watch out for
- Interpolating shell variables into hand-written JSON strings; quotes or newlines in the value break the body.