The command
curl -i -H "Origin: https://app.example.com" https://httpbin.org/get
Opens the request console with this request filled in. It is sent from api-tester.com's server rather than from your machine, so it shows what the endpoint returns, not how your own network or curl build behaves.
What the flags do
| Flag | What it does |
|---|---|
-H "Origin: https://site" | Pretend the request comes from a page on that origin. |
-i | Show response headers, where the CORS answer lives. |
-X OPTIONS | Send the preflight request. |
The simple case
A browser adds an Origin header to every cross-origin request and then looks for Access-Control-Allow-Origin in the response. If that header is missing, or names a different origin, the browser withholds the response from the script, even though the server processed the request and returned 200. Send the same Origin with curl and read the header yourself.
The value must be either the exact origin, scheme and port included, or *. And * is not accepted when the request carries cookies or HTTP authentication; then the server must echo the specific origin and also send Access-Control-Allow-Credentials: true.
curl -s -i -H "Origin: https://app.example.com" https://httpbin.org/get \
| grep -i "^access-control"
The preflight
Requests that could change data in ways an HTML form could not, such as a JSON POST, a PUT or DELETE, or anything with a custom header like Authorization, are preceded by an OPTIONS preflight. The browser sends the method and headers it intends to use; the real request goes out only if the response approves all of them. Reproduce it, and the failing part is usually obvious: a method or header missing from the allow lists, or a non-2xx status.
curl -i -X OPTIONS https://httpbin.org/post \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: content-type, authorization"
Common mistakes
- "It works in curl but not in the browser" is the definition of a CORS problem, not evidence against one. The server must send the right headers; nothing on the client can fix it.
- Some servers only add CORS headers when
Originis present, so a curl test without it proves nothing. - A cached preflight (
Access-Control-Max-Age) can make a browser keep using an old answer after you fixed the server.
Related curl examples
Curl OPTIONS Request Example
OPTIONS asks a server what it would accept at a URL.
Curl Send Header Example
-H adds a header line to the request.
Curl HEAD Request Example
HEAD asks for the headers a GET would return and nothing else.
Curl GET Request Example
GET is what curl does when you give it nothing but a URL.
CORS Tester
Run a real cross-origin fetch from your browser and see whether the response is readable.
CORS Explained
The same-origin policy, preflights and credentials in depth.
All Curl Examples
49 worked examples, grouped by what you are trying to do.
More under Network behaviour
References
- curl man page: -H — Adding the Origin and Access-Control-Request headers.
- MDN: CORS — The full preflight and response-header rules browsers apply.
These links leave api-tester.com, which is independent of the projects they point to.
FAQ
How do I test CORS with curl?
Send the request with an Origin header and -i, then check the response for Access-Control-Allow-Origin. For non-simple requests, also send an OPTIONS preflight with Access-Control-Request-Method.
Why does my request work in curl but fail in the browser with a CORS error?
Curl does not enforce the same-origin policy. Browsers do, and they block a script from reading a cross-origin response unless the server sends matching Access-Control-Allow-* headers.
Can I bypass CORS with curl?
Curl is not subject to CORS in the first place. That does not help a web page, whose requests are still made by the browser; the fix must be made on the server or through a same-origin proxy.