Skip to content

cURL GET request: query strings, headers and output

Send GET requests with curl: quote the URL, build the query with -G and --data-urlencode, check it with -w. Every command run on 11 October 2026.

HProxy TeamOctober 11, 2026Updated October 11, 20268 min read

cURL GET request: query strings, headers and output

curl sends a GET request whenever you give it only a URL: curl https://example.com/. To add parameters, put the whole URL in single quotes. Or let curl build the query with -G and --data-urlencode, which also encodes the values. Check what went out with -w '%{method} %{http_code} %{url.query}'. We ran every command on this page on 11 October 2026 with curl 8.5.0 on Ubuntu 24.04, against httpbin.org and example.com.

Most failed GET requests are not curl's fault. The shell cuts the URL at an & or refuses a ?, or curl reads braces and brackets as its own patterns. Those traps follow the basics.

How do you send a GET request with curl?

Give curl the URL. With nothing else, it sends a GET. As the everything curl guide puts it, "GET is default, using -d or -F makes it a POST, -I generates a HEAD and -T sends a PUT".

curl https://example.com/

In our run, example.com answered 200 with 577 bytes of HTML. With -v, curl showed the request line it sent, GET / HTTP/2, and three headers: Host, User-Agent: curl/8.5.0 and Accept: */*.

You do not need -X GET. The manual says that "normally you do not need this option", because it "only changes the actual word used in the HTTP request". Our request line was the same with and without it.

Terminal output: a bare URL sends GET, the request line with and without -X GET, two ways to add parameters, and -d against --data-urlencode
Our own capture, curl 8.5.0 on Ubuntu 24.04, 11 October 2026

How do you add query parameters?

There are three ways. In our run, all three reached httpbin.org with the parameters we meant.

  1. Write them into the URL, and quote the whole URL. Single quotes keep "the literal value of each character", so the shell hands the ? and the & to curl untouched.

    curl 'https://httpbin.org/get?country=de&limit=5'
    
  2. Let curl build the query. -G takes the -d data and "appends the provided data to the URL as a query string", instead of sending a POST.

    curl -G -d country=de -d limit=5 https://httpbin.org/get
    
  3. Add to an existing query with --url-query, available since curl 7.87.0. It encodes the value, adds the & itself and keeps the method. With a -d beside it, curl sent a POST with limit=5 in the URL and name=alice in the body.

    curl --url-query 'city=São Paulo' 'https://httpbin.org/get?country=br'
    

When do values need encoding?

-d sends its text "exactly as provided on the command line", and "curl does not convert, change or improve it". A server that reads the query as form data turns every + into a space, as the URL standard spells out. So -G -d 'q=C++' reached httpbin as C and two spaces.

--data-urlencode encodes the value first:

curl -G --data-urlencode 'q=C++' --data-urlencode 'city=São Paulo' https://httpbin.org/get

Both values arrived intact. curl 8.5.0 wrote the query as q=C%2b%2b&city=S%c3%a3o+Paulo. Lowercase and uppercase hex mean the same in a URL, and curl switched to uppercase in 8.15.0. Typed straight into the URL, a São left our 8.5.0 as raw bytes, although curl's own URL page says it encodes them. --data-urlencode avoids the question.

How do you add headers and save the answer?

-H adds a header to the request, such as an Accept header or an API key. "You may specify any number of extra headers."

curl -s -H 'Accept: application/json' -H 'X-Api-Key: KEY' 'https://httpbin.org/get?country=de'

httpbin received both headers with the query. For the answer itself, -o answer.json writes it to a file instead of the terminal: 289 bytes in our run. -s hides the progress meter, and -S still shows errors when -s is on. -i prints the response headers first, starting with the status line, HTTP/2 200 here. Our curl headers guide covers headers in depth.

How do you check what curl sent?

-w prints details after the transfer. %{method}, %{http_code} and %{url.query} show the method, the status and the encoded query:

curl -s -o /dev/null -w '%{method} %{http_code} %{url.query}\n' -G --data-urlencode 'q=C++' --data-urlencode 'city=São Paulo' https://httpbin.org/get

Our run printed GET 200 q=C%2b%2b&city=S%c3%a3o+Paulo. %{url.query} needs curl 8.1.0 or later.

By default, curl does not treat an HTTP error as a failure: a 404 ended with exit code 0. With -f, curl printed The requested URL returned error: 404 and exited with 22, which a script can catch.

Terminal output: --url-query on a GET and a POST, -w with the method, status and query, -f on a 404, and what a proxy sees over http and https
Our own capture, curl 8.5.0 on Ubuntu 24.04, 11 October 2026. The proxy was our stub on 127.0.0.1 with a placeholder login.

Which mistakes break a GET request?

MistakeWhat happened in our runFix
An unquoted & in bashcurl got only ?country=de, and limit=5 became a shell variableSingle quotes around the URL
An unquoted ? in zshNot run here: zsh stops with "no matches found"Quotes
An & in the Windows command promptNot run here: the prompt treats it as a second commandQuotes, or ^&
JSON in bracesTwo requests, each with half of the JSON, exit code 0-G --data-urlencode, or -g
Brackets, as in page[size]=10curl: (3) bad range in URL position 30-g
A space in the URLcurl: (3) URL rejected: Malformed input to a URL function--data-urlencode, or %20
-d without -GA POST, which httpbin's /get refused with 405Add -G
-X GET with -dA GET that carried the data as a body-G instead
-GETRead as -G -E T; exit code 58 over https://-G, or nothing

The ampersand. In bash, a command ended by & runs "in the background", and the shell "does not wait for the command to finish". So the shell started curl with half of the URL and set limit=5 as a variable. curl's manual gives the same advice. Put the full URL in quotes "to avoid the shell from interfering with it", because of characters such as & and ?.

zsh and the command prompt. Since macOS 10.15, zsh is the default shell on a Mac. Its NOMATCH option makes it "print an error" when a pattern such as an unquoted URL with ? matches no file. bash leaves the word unchanged in that case, which is why the same command works in bash and fails in zsh. In the Windows command prompt, & is one of the special characters "that must be preceded by the escape character ^ or quotation marks".

Braces and brackets. curl reads {a,b} as a list and [1-9] as a range, so a JSON value in braces became two requests. -g (--globoff) turns that off.

A body on a GET. RFC 9110 says that content in a GET request "has no generally defined semantics". Such content also "might lead some implementations to reject the request". Use -G to put the data into the query instead.

-GET. curl joins short options, so -GET means -G plus -E T, a client certificate file named T. Over https://, our curl stopped with exit code 58, "could not load PEM client certificate from T".

Terminal output: an interactive bash session where an unquoted & cuts the query, then braces, brackets, a space, -d without -G, -X GET with -d, and -GET
Our own captures, bash 5.2 and curl 8.5.0 on Ubuntu 24.04, 11 October 2026

What does a proxy see of your GET request?

It depends on the scheme. For an http:// address, the client sends the proxy the whole URL, query included, "in absolute-form". For https://, it sends "only the host and port" in a CONNECT request, and the query travels inside the encrypted tunnel. Our stub proxy logged GET http://httpbin.org/get?country=de&limit=5 for the first and CONNECT httpbin.org:443 for the second.

So keep secrets out of query strings where you can. RFC 9110 warns that servers and proxies "log or display the target URI in places where it might be visible to third parties". An API key in a header does not appear in a logged URI, but over plain http:// a proxy can read the headers too.

To send a GET through a proxy, add -x with the proxy URL. With our gateway's address and placeholder credentials:

curl -x http://USER:PASS@premium.hproxy.com:10000 'https://httpbin.org/get?country=de&limit=5'

We ran the same command through our stub proxy in place of the gateway. Lines from our residential proxies use this form when you need an exit address other than your own. Our guide to using proxies with curl covers the other proxy options.

What this page could not check

  • We ran one curl build, 8.5.0 on Ubuntu 24.04 with bash 5.2. Newer behaviour comes from the manual and the changelog; the latest release on 11 October 2026 was 8.22.0.
  • zsh and the Windows command prompt were not run. Those rows rest on the zsh manual, Apple's help page and Microsoft's documentation.
  • httpbin.org decoded our queries with its own rules, such as a + as a space, which other servers may not share.
  • The proxy was our stub on 127.0.0.1, which logs the request line. A real proxy may log more or less.
  • Raw non-ASCII bytes in the URL left our 8.5.0 unencoded, while curl's URL page says curl encodes them. We did not test a newer build.
  • One httpbin answer failed once and passed a minute later; we do not know why.
  • curl releases every eight weeks, and write-out variables and encoding details change. We will run these commands again by 11 January 2027.

Sources

  • curl manual, curl project, current version, read 11 October 2026: curl.se.
  • everything curl: method, request method, query and convert to GET, read 11 October 2026: everything.curl.dev.
  • curl documentation, URL syntax, read 11 October 2026: curl.se.
  • curl changelog, releases 8.15.0, 8.21.0 and 8.22.0, read 11 October 2026: curl.se.
  • RFC 9110, HTTP Semantics, sections 9.3.1 and 17.9, IETF, June 2022: rfc-editor.org.
  • RFC 9112, HTTP/1.1, sections 3.2.2 and 3.2.3, IETF, June 2022: rfc-editor.org.
  • RFC 3986, URI Generic Syntax, sections 2.1 and 3.4, IETF, January 2005: rfc-editor.org.
  • WHATWG URL Standard, application/x-www-form-urlencoded parsing, read 11 October 2026: url.spec.whatwg.org.
  • GNU Bash Reference Manual: lists of commands, single quotes and filename expansion, read 11 October 2026: gnu.org.
  • zsh manual, options (NOMATCH), and Apple Support on zsh as the default shell, read 11 October 2026: zsh.sourceforge.io.
  • Microsoft Learn, cmd, read 11 October 2026: learn.microsoft.com.
  • Our own runs, 11 October 2026, 01:42 to 02:37 UTC, from our server: about 50 requests to httpbin.org and example.com, and a stub proxy on 127.0.0.1.

Frequently asked questions

How do I send a GET request with curl?

Give curl the URL: curl https://example.com/. GET is the default method, so you do not need -X GET. With and without it, our curl 8.5.0 sent the same request line, GET / HTTP/2.

How do I add query parameters to a curl GET request?

Put the whole URL in single quotes: curl 'https://httpbin.org/get?country=de&limit=5'. Or let curl build the query: curl -G -d country=de -d limit=5 https://httpbin.org/get. Use --data-urlencode instead of -d for values with spaces, + or letters outside ASCII.

Why does curl drop part of my query string?

Because the shell cut the URL before curl saw it. In bash, an unquoted & ends the command and runs it in the background. In our test curl received only ?country=de, and limit=5 became a shell variable. Put the URL in single quotes.

What is the difference between curl -GET and -X GET?

-X GET sets the method word, which is GET anyway. -GET is read as -G followed by -E T, a client certificate file named T. Over https:// our curl stopped with exit code 58 because there was no such file.

Can I send JSON in a curl GET request?

Put it into the query with -G --data-urlencode 'filter={...}'. Unquoted braces are a curl list: our test made two requests, each with half of the JSON. A body on a GET has no defined meaning in HTTP, and some servers reject it.

Why does zsh say no matches found for my curl URL?

zsh reads the ? in an unquoted URL as a file pattern, and its NOMATCH option makes it stop when no file matches. zsh is the default shell on a Mac since macOS 10.15. Put the URL in quotes.

Get proxies that are alive right now

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump. When the location has to survive a real check, the paid network holds up.

129M+ proxy checks run · 100+ countries · HTTP / HTTPS / SOCKS · re-checked every few minutes · no signup

HProxy.

Honest guides and comparisons on proxies, scraping and staying unblocked, from the team that runs the network.

RSS feed