The splitting is the hard part
Before any option can be read, the command has to be broken into arguments the way a shell would break it, and that is where naive converters go wrong. Inside single quotes, nothing is special — a backslash is a backslash and a dollar sign is a dollar sign. Inside double quotes, a backslash escapes only a small set of characters and everything else stays literal. Outside quotes, a backslash at the end of a line joins it to the next one, which is how the multi-line commands that browsers generate hold together.
Get that wrong and a JSON body full of escaped quotes comes out mangled, usually in a way that still looks plausible. This page implements the quoting rules directly and, when a quote is left open, says so instead of producing code from a bad split. Commands copied from Windows are handled for line continuation with a caret, but a command written for PowerShell uses different quoting rules again and may not split correctly.
Which options map, and to what
| curl option | What it becomes |
|---|---|
-X, --request | The method. With no -X, a body implies POST and no body implies GET |
-H, --header | An entry in the headers object |
-d, --data, --data-raw | The body. Several of them are joined with an ampersand, as curl does |
-u, --user | An Authorization header built with btoa |
-b, --cookie | A Cookie header, which a page normally cannot set |
-A, -e | User-Agent and Referer headers |
--compressed, -L | Nothing. Both are browser defaults already |
-k, -x, -E, -o, -F, -T | Listed as not translatable, with what to do instead |
When no Content-Type is given and there is a body, application/x-www-form-urlencoded is added, which matches what curl sends for -d. That is frequently not what you want: a JSON body needs application/json and will often be rejected without it. The generated code is a starting point you read, not output you paste unread.
What a browser will not let you do
curl runs as a program with full control of the socket. A page runs inside a security model that exists to stop one site acting as another. Several headers are managed by the browser and refused when script tries to set them: Cookie, Host, Content-Length, Connection and others in that family. The exact list has changed over time and differs a little between browsers, so the right posture is to expect a refusal and test rather than to assume.
Cookies are the case worth spelling out. A captured request carries a Cookie header because curl was told to send one. From a page, you do not set it — you pass credentials: "include" and the browser attaches the cookies it already holds for that origin, subject to the cookie attributes and the CORS response. And none of it works at all unless the server sends the right Access-Control-Allow-Origin and friends, which a curl command never had to care about.
A copied request is a live credential
This deserves stating flatly rather than as a footnote. Copy as cURL captures the request exactly as it was sent, which means the bearer token, the session cookie and the API key are all in the text you just pasted, and they will still work for anyone who reads them. People paste these into issue trackers, chat channels and public questions constantly, and the credential is valid until someone notices and rotates it.
Redact before sharing. The checkbox on this page will swap credential-looking header values for a placeholder in the generated code, and the results panel lists which headers it considered sensitive so you can check by eye. It matches on common names, so it will miss a token in a header your organisation named something unusual. Read the output before it leaves your machine.
Reading the response, which curl did for free
On the command line the response body appears on your terminal. In code, it does not: fetch resolves as soon as the headers arrive and gives you a response object you have to read, and it does not reject on a 404 or a 500 the way people expect. That is why the generated code checks res.ok before parsing. If the endpoint returns something other than JSON, swap res.json() for res.text() and look at what actually came back — an HTML error page from a proxy is a common surprise. The status code reference covers what the number means, and the API response viewer is a decent next stop once you have a body in hand.
Questions people ask
Will the generated code actually run in a page?
It will run, but whether the request succeeds depends on things the curl command never had to satisfy. Cross-origin requests need the server to send permissive CORS response headers, a preflight OPTIONS request goes out first for anything beyond a simple request, and several headers in the command may be refused outright. Treat the output as a faithful translation of the request, not a guarantee that the browser will be allowed to make it.
Why did it add a Content-Type I did not ask for?
curl sends application/x-www-form-urlencoded by default for -d, so the same default is applied when a body is present and no Content-Type header was given. If your body is JSON, that default is wrong and the server will often reject it. Change it to application/json in the generated headers. The value is only added when the command did not set one itself.
Does it handle a command copied from PowerShell?
Partly. Line continuation with a caret is handled, and a command with straightforward quoting will usually split correctly. PowerShell has its own quoting and escaping rules that differ from a POSIX shell, particularly around backticks and doubled quotes, so a complex body may split wrongly. If the parsed body in the results panel does not look like the one in your command, that is what happened.
Is the command executed or sent anywhere?
Neither. The text is split into arguments and read option by option as data. No request is made from this page, nothing is evaluated as code, and the command never leaves the tab. That matters because the input here is almost always a real request against a real system with a real token in it.
What about -F for file uploads?
It is reported rather than translated, because the shapes are genuinely different. A page cannot read a path from disk; it gets a File object from an input element or a drop event. Build a FormData, append your fields and the file to it, and pass it as the body without setting Content-Type yourself, so the browser can generate the multipart boundary. Setting the type by hand is the usual cause of a multipart upload that the server cannot parse.