Web and API tool

cURL Converter: Convert cURL to Python, JavaScript, Go and PHP

Convert a cURL command to Python, JavaScript fetch, axios, Go or PHP code. Paste from Chrome Copy as cURL; it is parsed in your browser, never run.

Last updated

A cURL command is how most API documentation, bug reports and browser network tabs show an HTTP request. A program needs the same request as code. This converter reads a curl command and writes it as JavaScript fetch, Node.js axios, Python requests, Go net/http or PHP, with the method, URL, headers, body, login and cookies carried over.

Convert to

Read as POST https://api.example.com/cats. The command is only read, never run, and nothing leaves your browser.

Python (requests)

import requests

response = requests.post(
    "https://api.example.com/cats",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer YOUR_TOKEN",
    },
    json={
        "name": "Mittens",
        "age": 3,
    },
    allow_redirects=False,
)

print(response.status_code)
print(response.text)

Python 3 with the requests package (pip install requests).

The command is only read, never run. Nothing you paste is uploaded and the URL is never fetched, so it is safe to try with a request from a private API. Swap real tokens for placeholders before you share the code, though.

How to use it

  1. Paste a cURL command in the top box. A command that runs over several lines, with a backslash at the end of each, is fine.
  2. Pick the language under Convert to.
  3. Read the line above the code, which says how the command was understood, for example Read as POST https://api.example.com/cats.
  4. Check Not converted and Ignored if they appear. Every flag the tool saw is in one of the two lists, or in the code.
  5. Tap Copy and paste the code into your project.

Copying a request from your browser

The quickest way to get a cURL command for a request is the browser itself.

  1. Open DevTools and go to the Network tab.
  2. Reload the page or trigger the request, then right-click it in the list.
  3. Choose Copy, then Copy as cURL (bash). On Windows, Copy as cURL (cmd) writes the version for the command prompt.
  4. Paste it here.

Both formats work. The bash one quotes a body with a newline or a non-ASCII character as $'...', and the cmd one escapes with ^ and ends each line with ^. The tool reads both, and says Windows cmd syntax above the box when it detects the second.

Browsers add a lot of headers (sec-ch-ua, accept-language, sec-fetch-mode). They are all converted, because the converter cannot know which ones the server needs. Delete the ones you do not need from the code.

What is converted

cURLWhat the code does
-X, --requestSets the method. Without it, curl sends POST when there is a body and GET otherwise
-H, --headerSets a header. -H 'Name:' removes one and -H 'Name;' sends it empty
-d, --data, --data-raw, --data-binary, --data-asciiSends the text as the body. Several are joined with &
--data-urlencodePercent-encodes the value the way curl does, then sends it as the body
--jsonSends the body and sets Content-Type and Accept to application/json
-G, --getMoves the -d data into the query string and sends a GET
-F, --form, --form-stringSends a multipart form, with text and file fields
-u, --userBasic authentication. The same goes for user:password@ in the URL
--oauth2-bearerSets Authorization: Bearer ...
-b, --cookieSets the Cookie header from name=value pairs
-A, -eSets User-Agent and Referer
-L, --locationFollows redirects. Without it the code does not follow them, as in curl
-k, --insecureSkips certificate checks, or says in a comment that the language cannot
--compressedAsks for a compressed response and decodes it, or notes that the library already does
-I, --headSends a HEAD request
--urlTakes the URL from the flag instead of an argument

Flags can be combined (-sSL), attached to their value (-XPOST, -H'X-Id: 7') or joined with an equals sign (--header='X-Id: 7'). The URL can come before, between or after them. A URL with no http:// gets one, as in curl.

What is listed instead of converted

A converter that quietly drops a flag gives you code that behaves differently from the command, and nothing tells you. This one never does that.

  • Ignored are flags that do not change the request: -s, -S, -v, -i, -f, -o file, -O, -w, timeouts and retries, and the HTTP version flags. Anything after a pipe, a ;, a && or a > is ignored too, because the shell runs it after curl.
  • Not converted are flags that do change the request and have no equivalent here: a proxy (-x), client certificates (--cert), a CA bundle (--cacert), digest and NTLM authentication, DNS overrides (--resolve), a body read from a file (-d @file), a cookie file, a second URL, and any option the tool does not know. Each one is shown with its value and the reason.
  • Warnings cover what is not a flag, such as a $TOKEN that the shell would have filled in and the tool keeps as text.

Each language

JavaScript fetchNode.js axiosPython requestsGo net/httpPHP
Runs onBrowsers and Node.js 18+Node.jsPython 3Go standard libraryPHP curl extension
-uAuthorization headerauth optionauth=SetBasicAuthCURLOPT_USERPWD
-Lthe defaultthe defaultthe default (not for HEAD)the defaultCURLOPT_FOLLOWLOCATION
no -Lredirect: "manual"maxRedirects: 0allow_redirects=FalseCheckRedirect returns ErrUseLastResponsethe default
-kno option, a comment says sohttps.Agentverify=FalseInsecureSkipVerifyCURLOPT_SSL_VERIFYPEER and _VERIFYHOST
--compressedautomaticautomaticautomaticautomatic, unless you set Accept-EncodingCURLOPT_ENCODING
-FFormDataFormDatafiles=mime/multipartCURLOPT_POSTFIELDS array and CURLFile

The PHP code uses the curl extension, which most installs include and which mirrors curl option for option. Guzzle or Symfony HttpClient would do the same job, but need Composer, so the extension is the one that works everywhere.

A JSON body is written as a native object (a dictionary in Python, an object literal in JavaScript) only when that sends the same data. Large integers, numbers like 1.0, escaped characters and keys that would reorder do not survive the trip through an object, so those bodies stay as the exact string curl sent. Strings are quoted by each language's own rules, so quotes, backslashes, newlines and non-ASCII text in a body come out as a literal that means the same thing.

Common gotchas

  • Shell quoting is not part of the request. curl -H "Authorization: Bearer $TOKEN" has the shell fill in $TOKEN. The tool cannot, so it keeps the text and warns you. Replace it with the real value, or read it from an environment variable in your code.
  • -d is not JSON. -d '{"a":1}' sends the form content type unless a Content-Type: application/json header is set, and many APIs reject that. Use --json, or add the header.
  • -G is not a body. curl -G -d q=cats sends GET /search?q=cats, with the data in the query string and no body. Without -G, -d makes a POST.
  • Browsers will not let fetch set every header. Cookie, Host, Origin, Referer and Accept-Encoding are ignored in a browser and sent as written in Node.js. The converted code notes it when the command has one.
  • fetch cannot send a body with GET or HEAD. curl can. The converted code has a comment when the command does.
  • Redirects differ. See the table above. The converter copies what curl did, so a command without -L gives code that stops at the 301.
  • A file path is the path on the machine that ran curl. -F file=@photo.png becomes code that opens photo.png. Change it to where the file lives.
  • Do not paste live secrets into any website. This one never sends them anywhere, but a pasted token also ends up in your clipboard history and your shell history. Rotate a token that has been through either.

Common questions

What is a cURL converter?

A cURL converter reads a curl command and writes the same HTTP request as code in another language, so you can move a request from a terminal, an API's documentation or your browser's network tab into a program. This one writes JavaScript fetch, Node.js axios, Python requests, Go net/http and PHP code, and it keeps the method, URL, headers, body, login and cookies.

How do I convert a cURL command to Python?

Paste the command into the box above and choose Python. You get a requests call with the same method, URL, headers and body, plus the options that map to curl flags: auth for -u, verify=False for -k and allow_redirects for -L. A JSON body that survives the round trip is written as a Python dictionary passed as json=.

Does it run my cURL command or send the request?

No. The command is read as text in your browser and turned into code. Nothing is executed, the URL is never fetched and nothing you paste is uploaded. The site records that the tool was used, the language you picked and how long the command was, so we know which tools are worth building next. The command itself is never part of that.

How do I copy a request as cURL from Chrome?

Open DevTools, go to the Network tab, right-click the request, choose Copy, then Copy as cURL (bash), or Copy as cURL (cmd) on Windows. Paste the result here. Both formats are read, including the quoting Chrome uses for bodies with newlines and non-ASCII characters. Edge has the same menu, and Firefox has it under Copy Value.

Why did a -d request turn into a POST?

Because curl does the same. Any of -d, --data, --data-raw, --data-binary, --data-urlencode, --json or -F makes curl send a POST unless you also pass -X. A -d body also gets the header Content-Type: application/x-www-form-urlencoded unless you set your own, and the converter writes that header out so the code sends exactly what curl would.

What is the difference between -d, --data-raw and --data-binary?

For text on the command line they send the same bytes. The difference is the @ sign: -d and --data-binary treat @file as a file to read, while --data-raw sends the characters as they are. Chrome uses --data-raw so a body that starts with @ is not mistaken for a file. Reading a body from a file is not converted here, so the tool lists it instead.

Which cURL options does it convert?

The method (-X), URL (including --url), headers (-H), bodies (-d, --data-raw, --data-binary, --data-urlencode, --json and -G), multipart forms (-F and --form-string), basic auth (-u and credentials in the URL), bearer tokens (--oauth2-bearer), cookies (-b), -A, -e, --compressed, -L, -k and -I. Options that only change what curl prints, such as -s, -v and -o, are listed as ignored. Options that change the request and are not converted, such as proxies and client certificates, are listed as not converted.

What happens to -k and --compressed in each language?

-k becomes verify=False in Python, an https.Agent with rejectUnauthorized set to false in axios, a tls.Config with InsecureSkipVerify in Go and the CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options in PHP. fetch has no such option, so the code carries a comment saying so. --compressed needs nothing in fetch, axios, requests or Go because they ask for gzip and decompress on their own, and it becomes CURLOPT_ENCODING in PHP.

Why does the converted code not follow redirects?

curl does not follow redirects unless you pass -L, but fetch, axios and requests do by default. So when the command has no -L, the converted code switches following off to match curl, and when it has -L the code follows them. If you would rather follow redirects, delete that option.

Does it handle file uploads with -F?

Yes. A -F name=value field becomes a text field and -F name=@path becomes a file field, with the filename and type= you gave. The code opens the file at that path, so change the path to where the file lives. Reading a field's value from a file with name=<path and sending a file from standard input are not converted.

See all tools

Want this explained by a cat?

The videos cover the same ground in sixty seconds. If there is a tool you want built next, ask.