cURL Converter
runs in your browserPaste a cURL command and get the same request as JavaScript fetch, axios, Python requests or Go. Headers, JSON bodies and basic auth all carried across.
Paste the whole command, including the word curl. Line continuations, smart quotes and a copied $ prompt are all fine.
cURL command
fetch
about this tool
Paste the command, pick a language
cURL is what API documentation gives you and what your browser's devtools hand
back from "Copy as cURL". It is almost never what you are actually writing. This
reads the command and prints the same request as fetch, axios, Python
requests or Go.
Paste the whole thing, starting with the word curl. The line continuations, the
curly quotes a documentation site left in, and the $ from a copied shell
prompt are all handled — refusing those would be technically correct and no use
to anybody.
One parse, four languages
The command is read once into a plain description of a request — method, URL, headers, body, credentials — and each language is printed from that same description. It is worth saying why: a quoting bug in the Go output cannot make it disagree with the Python output about what you asked for, because neither of them ever looks at your command directly.
That also means the rules cURL itself applies are applied here. A command with
-d and no -X is a POST, because that is what cURL does. Repeated -d flags
are joined with &. -A, -b and -e are really just headers, so that is
what they become.
Bodies
A body sent with Content-Type: application/json is printed as an object rather
than a string, which is what you would have written by hand. fetch gets
JSON.stringify, axios gets data, and Python gets json=, which is how
requests wants a JSON body.
Python's True, False and None are spelled the way Python spells them. A
snippet that does not run is worse than no snippet.
Anything else is sent as text, unchanged.
-d makes cURL set a Content-Type of its own, and fetch and requests set
none, so the snippet writes one out rather than letting the request go as
text/plain. cURL always sends application/x-www-form-urlencoded there, and
so does the snippet — except when the body is JSON, where it writes
application/json instead, because a JSON body sent as a form is a command that
happens to work against a lenient server rather than one you want copied into
code. That is the single place the generated request differs from what cURL
would have sent. A Content-Type you gave yourself is always left as you wrote
it, in either case.
What it will not do
A flag it does not recognise is skipped and mentioned, rather than failing the
whole command — a stray --retry 3 should not cost you your code.
Some flags have no honest equivalent. -k turns off certificate checking, and
none of the generated snippets do that, because the fix is the certificate.
-o, --proxy and the timeout flags belong to the shape of a command-line
program rather than to the request itself. Each one produces a note saying it
was left out.
-F is read and its fields are carried over, but a real upload needs a real
file, so the snippet gives you the shape and leaves the file to you.
Nothing is sent
The command is parsed here and the code is written here. No request is made, which matters more on this page than on most: a cURL command copied out of devtools usually has a live session token sitting in a header.
To pull a URL apart rather than the command around it, use the URL parser. To read the token you just pasted, use the JWT decoder.
questions
- Which flags does it understand?
- The ones people actually paste: -X, -H, -d and its --data variants, -F, -u, -A, -b, -e, --url, and the bare switches like -L, -k and --compressed. A flag it does not know is skipped with a note rather than failing the whole command, so a stray --retry 3 still gets you your code.
- Does the command leave my browser?
- No. The parsing and the code generation both run in this page, and no request is ever sent. That matters here more than on most tools, because a cURL command copied from devtools usually has a live session token in it.
- Why does my POST show up without -X POST in the original?
- cURL sends POST automatically when you give it a body with -d, so a command with data and no method is a POST. The converter follows the same rule, which is why the method appears in the output even though it was not in the input.
- What happens to -u?
- It becomes the Authorization header cURL would have sent — Basic, with the credentials base64-encoded. If the command already carries its own Authorization header, that one is kept and -u is left out rather than sending two.
- Will the Python snippet run as it is?
- It should. A JSON body is passed with json= and anything else with data=, and the Content-Type is written into the headers dict rather than left to requests — application/json for a JSON body, application/x-www-form-urlencoded otherwise, which is what cURL sends. The booleans and nulls in the payload are spelled True, False and None — the real ones only, never the word true sitting inside a string. A method requests has no function for, like PURGE, goes through requests.request.
- Can it do multipart uploads?
- It reads -F and carries the fields over, but a real file upload needs a file, which a browser tool cannot invent. You get the shape of the request and a note saying to attach the file yourself.