Quoting Hell: Why Your cURL Command Breaks in Bash, zsh, and Windows
A curl command fails in four distinct ways, and only one of them is the server's fault. Before blaming the API, blame the shell. If you've ruled out quoting, the next suspect is usually a header or encoding mismatch — see curl works, my code fails.
Single quotes are boring. Use them.
-H 'Authorization: Bearer ***' is inert. Double quotes invite expansion: $VAR interpolates (usually what you want), but backticks and $(...) interpolate too, and a JSON payload containing $(...) becomes a command your shell executes. If the body has no variables, single quotes. Always.
Windows is three shells and they disagree
- cmd.exe has no quote stripping worth the name.
curl -H 'Content-Type: application/json'sends a header literally named'Content-Typewith a value starting withapplication/json. Double quotes and escape the inner ones:-H "Content-Type: application/json". - PowerShell (5.1) steals
curlas an alias forInvoke-WebRequestunless you callcurl.exe. Its quote parser then breaks=and@in ways that look like malware behavior. Windows Terminal's PowerShell 7+ is better;curl.exeis safest. - Git Bash behaves like Linux. If your team uses Windows, Git Bash is the least pathological environment for pasting copied commands.
Here-docs for readable POSTs
curl -X POST https://api.example.com/v1/jobs \
-H 'Content-Type: application/json' \
-d @- <<'EOF'
{ "model": "small", "input": "multi-line, no escaping" }
EOF
The <<'EOF' (quoted) blocks interpolation, so the JSON stays verbatim. -d @- reads the body from stdin. This one pattern retires most of the escaping complaints I get asked about.
Continuation lines
A backslash must be the final character on the line — trailing spaces after it turn the next line into a separate command, and you get the cryptic curl: (3) URL rejected because it parses -H as the URL. Our converter outputs one-line commands by default for exactly this reason; use the "pretty" option if your shell is disciplined.
FAQ
Why does my header arrive as 'Content-Type? Windows cmd.exe. It does not strip single quotes. Switch to double quotes or move to Git Bash.
Is "$TOKEN" in a double-quoted header safe? It interpolates, which is usually the point — but never double-quote a payload you copied from the internet. $(...) inside double quotes executes.
PowerShell keeps mangling my JSON body. Which shell should I use? curl.exe from PowerShell 7+, or Git Bash. Avoid Windows PowerShell 5.1 for pasted curl commands entirely.