Where a curl command comes from
The most common source by far is a browser’s own DevTools: open the Network tab, trigger the request, right-click it, and choose Copy → Copy as cURL. That gives you the exact request the browser sent (method, headers, cookies and body included), which is exactly what makes it worth converting rather than rebuilding by hand.
What gets carried over
| From curl | Becomes |
|---|---|
| The URL | The request URL in every language |
-X / --request, or POST when -d is used with no -X |
The HTTP method |
-H / --header |
A header, in each language’s own way of setting one |
-d, --data, --data-raw, --data-binary, --data-urlencode |
The request body, with Content-Type: application/x-www-form-urlencoded unless you set your own |
-d @file, --data-binary @file |
A body read from that file, with its CR and LF bytes stripped for plain -d/--data, exactly as curl does, and kept exactly for --data-binary |
--json |
A JSON body with Content-Type and Accept set to application/json, sent as a POST |
-F, --form, --form-string |
A multipart form, including @file uploads with ;type= and ;filename= |
-G |
The -d data appended to the URL’s query string, as a GET |
-I |
A HEAD request |
-T file |
The file as the body of a PUT |
-u user:pass, --oauth2-bearer token |
An Authorization: Basic … or Bearer … header, computed exactly as curl sends it |
-A, -b, -e |
User-Agent, Cookie and Referer headers |
-k |
Certificate checks switched off (custom Agent in axios, CURLOPT_SSL_VERIFYPEER in PHP, TrustManager in Java, verify=False in Python, InsecureSkipVerify in Go, OpenSSL::SSL::VERIFY_NONE in Ruby; fetch has no equivalent) |
A URL with no http:// |
http:// added, as curl does |
Flags that don’t change what gets sent over the wire (--compressed, -s/--silent, -L/--location, -v/--verbose and a few others) are recognised and quietly dropped, so a command copied straight from DevTools doesn’t need cleaning up first. Options that do something the generated code doesn’t (saving to a file, a proxy, a timeout) are listed under the code instead.
Copied from Chrome or Firefox
When a request body holds a quote, a newline or a control character, Chrome writes it as a $'…' string with escapes like \n, \' and \u0021. This page decodes them the way bash and zsh do, so the body in your code is the body that was sent, not a string full of backslashes. Repeated headers, including several Cookie headers, are folded into one, since a JavaScript object can only hold a header once.
Why the JSON body isn’t always “beautified”
When your curl command’s body is valid JSON, this page can render it as a real object literal: JSON.stringify({...}) in JavaScript, json={...} in Python, instead of an opaque string. That’s much nicer to read and edit.
But it only does this when the command actually says the body is JSON, via a Content-Type header that mentions it. Here’s why that guard matters: -d and --data-raw make curl automatically send Content-Type: application/x-www-form-urlencoded unless you set your own header, even when the text inside the quotes happens to look exactly like JSON. If this page “helpfully” converted that body into json= in Python, the generated code would send Content-Type: application/json instead, which is a different request to the one you copied, and might get a different response from the server, or fail outright, in a way that’s confusing to track down.
So: body looks like JSON and a JSON content type is present → you get a clean object literal. Body looks like JSON but there’s no JSON content type → you get the exact string, quoted and escaped, sent exactly as curl would have sent it. --data-binary and --data-raw get the same default as -d. Only a -T upload sends no content type of its own, and that is mirrored too.
Go, Ruby and Java, and why they’re more verbose
Neither Go’s net/http, Ruby’s net/http, nor Java’s HttpClient has a shortcut for “make an HTTP request” the way fetch or Python’s requests do: they are standard-library building blocks, not convenience wrappers. The generated code follows each one’s standard pattern: build a request object, set headers on it, run it through the client, then read the response body yourself. It’s more lines than fetch or Python, and that’s normal for these, not a sign that something’s missing.
It shows most in a multipart form (-F): Go’s net/http at least ships a multipart writer (mime/multipart), but Ruby and Java have no multipart support at all, so the generated code assembles the boundary-delimited body itself, field by field. It’s more code, but it’s exactly what a developer reaching for the standard library without a third-party dependency would write by hand.
Files and forms
-F becomes a multipart form and -d @file a body read from disk. The generated code opens the file at the path in your command, so the path has to exist where the code runs. Uploaded files carry the content type curl would give them: your ;type=, else a guess from the extension, else application/octet-stream. In fetch that means Node.js (it reads files with fs); Python and Go read them natively.
Credentials
A pasted command often carries a live token or cookie. When it does, a note names where (the Authorization header, a cookie, an API-key header, or a token=/key= in the URL) and Hide credentials replaces each value with REDACTED in the generated code, keeping the scheme (Bearer REDACTED) and cookie names so the shape is still clear. It doesn’t look inside the request body.
What it can’t do
It can’t read data from standard input (@-), or --data-urlencode with an @file, because there is no file to read inside a browser tab. It doesn’t attempt Windows cmd’s own quoting conventions: paste the bash/zsh-flavoured command (what “Copy as cURL (bash)” gives you, even on Windows) rather than the cmd-flavoured one. Digest and NTLM authentication, proxies, timeouts and cookie jars aren’t converted; each one is listed under the code when it appears in your command. -d @file removes line breaks from the file, as curl does, while --data-binary @file keeps it exactly: the generated code sends the file as it is, and says so when the difference matters.