The curl Converter, Explained
After reading this you can take any curl command, understand exactly what request it describes, and translate it by hand or by tool into fetch, axios, Python requests or PowerShell without silently changing the request.
What the converter does and one quick example
A curl command is a text description of one HTTP request. It names a method, a URL, some headers, and often a body. The curl Converter parses that text and rebuilds the same request in another language's HTTP client, keeping the method, headers, body, basic auth and form data intact.
Here is the hook. Take this command:
curl -X POST https://api.example.com/login -H "Content-Type: application/json" -d '{"user":"ada","pass":"lovelace"}'
The converter reads five facts from it: the method is POST, the URL is https://api.example.com/login, one header sets the content type, the body is a JSON string, and there is no authentication. In JavaScript fetch, those same five facts become:
fetch("https://api.example.com/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: '{"user":"ada","pass":"lovelace"}' })
Nothing about the request over the wire changed. Only the surrounding syntax did.
When to use it, and when to write the request by hand
Reach for the converter when someone hands you a working curl line and you need it inside application code. The most common source is your browser. Open DevTools, go to the Network tab, right-click a request, and choose Copy as cURL. You get a command with every header the browser sent, sometimes 15 or 20 of them. Pasting that into the converter turns it into fetch or requests in one step.
Do not use it as a substitute for understanding the request. A converter cannot know that the Cookie header expires in 30 minutes, or that a hard-coded Authorization token belongs to your personal session. It copies what you give it, faithfully, including the parts you should not ship.
A browser Copy as cURL often includes a live session cookie and a bearer token. If you paste the generated code into a public repository, you are publishing valid credentials. Strip the Cookie and Authorization headers before committing.
The parts of a curl command
There is no arithmetic here, but there is a grammar, and getting it wrong is where conversions break. A curl command is the word curl followed by a URL and a set of flags in any order. The converter recognises these:
-X- The HTTP method, such as
GET,POSTorDELETE. If you omit it, curl usesGET, orPOSTwhen a body is present. -H- One header, given as
"Name: value". Repeat the flag once per header. -d/--data/--data-raw/--json- The request body. Using any of these with no
-XimpliesPOST.--jsonalso setsContent-Type: application/jsonfor you. -u- Basic auth as
user:password. curl base64-encodes it into anAuthorizationheader. -F- One multipart form field, such as
-F "[email protected]". The@means "read this file". -G- Force the request to be
GETand append any-ddata to the URL as a query string instead of sending a body. -L- Follow redirects. In fetch this maps to the default
redirect: "follow"; some clients need it set explicitly.
Two rules cause most surprises. First, -d with no method is a POST, not a GET. Second, quoting matters: single quotes in a shell keep the text literal, so -d '{"a":1}' sends exactly {"a":1}, while shell interpolation inside double quotes can rewrite it before curl ever sees it.
How basic auth is encoded
The one place a conversion involves real computation is -u. Basic authentication, defined in RFC 7617, does not send your password directly. It joins the username and password with a single colon, base64-encodes the result, and prefixes it with the word Basic.
Here user is the name before the colon, password is everything after the first colon, and the colon between them is a literal separator. The base64 function encodes the byte string into the 64-character alphabet A-Z a-z 0-9 + /. Note the weakness: base64 is reversible by anyone. Basic auth protects nothing on its own, so it must ride inside HTTPS.
Encoding ada:lovelace
- Join with a colon:
ada:lovelace, which is 12 bytes. - Take three bytes at a time.
a,d,aare0x61 0x64 0x61. - Those 24 bits split into four 6-bit groups:
011000 010110 010001 100001, which index into the base64 alphabet asY,W,R,h. - Continue across all 12 bytes to get
YWRhOmxvdmVsYWNl. Twelve bytes become 16 base64 characters, exactly \lceil 12 / 3 \rceil \times 4 = 16. - The final header is
Authorization: Basic YWRhOmxvdmVsYWNl.
Every target language produces this same header. Python requests does it through auth=("ada","lovelace"), fetch through an explicit header, but the bytes on the wire are identical.
A worked example reproducing the demo
The demo starts from the login command shown at the top. Follow it through to each target.
From curl to four clients
Source: curl -X POST https://api.example.com/login -H "Content-Type: application/json" -d '{"user":"ada","pass":"lovelace"}'
| Target | Method | Body | Header source |
|---|---|---|---|
| fetch | method: "POST" | body: '...' | headers object |
| axios | axios.post(url, data) | data object | headers option |
| Python requests | requests.post | json={...} | headers dict |
| PowerShell | -Method Post | -Body '...' | -Headers @{} |
All four send one POST to the same URL with one header and a 33-byte JSON body. Count the body: {"user":"ada","pass":"lovelace"} is 33 characters, and since it is all ASCII, that is 33 bytes, which becomes the Content-Length.
Reading the converted output correctly
The value of a conversion is that you can verify it. Check three things every time.
First, the method. If your curl had no -X but had -d, the correct output is POST, not GET. A converter that shows GET here has a bug, or you dropped the data flag.
Second, the body encoding. A JSON string body and a form body are different requests. -d 'a=1&b=2' produces Content-Type: application/x-www-form-urlencoded unless you override it, while --json produces JSON. If the target uses json={...} where the source sent form data, the bytes differ.
Third, header count. Copy-as-cURL from a browser can carry a dozen headers. The output should list every one. A missing Accept or Referer can change the server's response.
Common mistakes that change the request
Most broken conversions come from the shell, not the tool.
- Line continuations. A pasted command with trailing backslashes and newlines is fine, but a stray unescaped newline inside a quoted body truncates it. Check that the body in the output matches the body you meant.
- Single vs double quotes. On Windows
cmd, single quotes are not string delimiters. A command copied from a macOS terminal with single quotes may not run as-is on Windows, and the body may include literal quote characters. - The
@in-dand-F.-d @file.jsonmeans "read the body from file.json", while-F "[email protected]"uploads a file. A converter targeting fetch cannot read your local file, so it can only show a placeholder. Fill in the real file handling yourself. - Assuming
-Lis free. Following redirects can resend your body and headers to a new host. fetch follows by default; some server-side clients do not. Confirm the redirect behavior when it matters.
If a converted request behaves differently from the original, run the original curl with -v. The verbose output prints the exact request line, headers and body curl sent, giving you a ground truth to compare the generated code against.
Related tools
A request rarely stands alone. When the server answers, the HTTP status codes reference tells you what the numeric response means. If you are picking apart the request URL itself, the URL parser and query editor splits it into host, path and query parameters you can edit in a table. To read the User-Agent header that a browser copy-as-cURL includes, use the User-Agent parser. And when you set a Content-Type by hand, the MIME type lookup confirms the right value for a given file extension.
Frequently asked questions
Does the converter send my request anywhere?
No. It runs entirely in your browser. The command you paste is parsed locally and never leaves your device, which matters because pasted commands often contain live cookies and tokens.
Why did my GET turn into a POST?
Because you used -d without -X GET. In curl, adding a body defaults the method to POST. If you want a GET with data in the query string, add -G.
Can it handle file uploads with -F?
It recognises the multipart form and builds the form structure, but it cannot read your local file. Where the source has -F "[email protected]", the output marks the file field so you can wire up the real FormData or file handle.
Why does the Python output use auth= instead of an Authorization header?
Both send the identical Authorization: Basic ... header on the wire. Python requests offers auth=(user, password) as a cleaner way to produce it, so the converter uses the idiomatic form for each language.
What if my curl uses a flag the converter does not list?
Unsupported flags are skipped, and the resulting request omits their effect. Check the output against the supported set: -X, -H, -d/--data/--data-raw, --json, -u, -F, -G, -L and the URL. Anything else needs a manual edit.