cURL to Code Converter

Convert cURL commands to Python requests, JavaScript fetch, Go net/http, PHP curl, and Node.js axios code instantly. No signup, runs in your browser.

  • Runs in your browser
  • Your data never leaves your browser
  • Free · No Sign-Up
Convert the current command. Review options listed as not converted at the top of the code. Ctrl/⌘+Enter also converts; editing the command alone does not.
Replace the input with a JSON POST example containing Content-Type and Authorization headers, then convert it in the selected language.
Clear the command, generated code and status while keeping the selected language. Ctrl/⌘+L within the tool also clears them.
Output language Choose Python, JavaScript, Go, PHP or Node.js. Tabs regenerate the last converted command. After editing the command, click Convert to apply the changes.
Enter a cURL command, including backslash line continuations or DevTools Copy as cURL (bash) quoting. This tool generates code without sending the request.
Generated Code
Copy all the displayed code for the selected language. Empty output is not copied. Review the generated request before running it in your project.

Enter a cURL command or load the example, then convert it to code.

Examples, details and FAQ Worked examples, how it compares with other tools, and answers to common questions.

Common Use Cases

  • API integration: Translate API examples from docs (usually cURL) into your preferred language.
  • Debugging: Copy a failing request from browser DevTools as cURL and convert it to test in code.
  • Onboarding: Help teammates who are unfamiliar with cURL understand what a request does.
  • Testing: Quickly scaffold HTTP calls without writing boilerplate by hand.

Example: A JSON POST

curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"name": "Alice", "email": "alice@example.com"}'

Python output:

import requests

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer TOKEN",
}

data = "{\"name\": \"Alice\", \"email\": \"alice@example.com\"}"

response = requests.post(
    "https://api.example.com/users",
    headers=headers,
    data=data,
    allow_redirects=False,
)
print(response.text)

Go output:

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader("{\"name\": \"Alice\", \"email\": \"alice@example.com\"}")
	req, err := http.NewRequest("POST", "https://api.example.com/users", body)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Authorization", "Bearer TOKEN")

	client := &http.Client{
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return http.ErrUseLastResponse
		},
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(respBody))
}

The body is the exact string you typed, so the server receives the same bytes as with curl. allow_redirects=False and http.ErrUseLastResponse are there because curl does not follow redirects unless you pass -L, while requests and Go’s http.Client follow them by default. The Go code stops with log.Fatal on every error instead of discarding it.

How the Code Is Checked

The tool’s test suite sends each sample command twice to a local HTTP server: once with the real curl binary and once with the generated Python, Go, and JavaScript code. The server compares method, path and query, headers, and body; multipart bodies are compared part by part, because the boundary is random. The Node.js output is checked as an ES module with node --check. The samples cover several -d options, -G, --json, --data-urlencode, -F file uploads, -d @file, Basic auth, HEAD, redirects with and without -L, and the $'...' quoting that Chrome writes.

How Options Are Converted

Rules follow the curl manual:

curlGenerated code
-X, --requestHTTP method; without it, a request with data is POST
-H, --headerHeader, name and value unchanged; Name; sends an empty value
-d, --data, --data-ascii, --data-raw, --data-binaryBody. Several of them are joined with &. Without a Content-Type header, Content-Type: application/x-www-form-urlencoded is added, as curl sends it
-d @file, --data-binary @fileThe code reads the file; for -d it removes CR and LF, as curl does
--data-urlencodename=content, =content, and content are URL-encoded (space becomes +)
--jsonBody, Content-Type: application/json, Accept: application/json, POST; several are joined without &
-G, --getThe data goes into the query string and the method is GET
-F, --formMultipart body: name=value, name=@file (upload, with ;type= and ;filename=), name=<file (file text as a value). The library writes the Content-Type with its boundary
-u user:passwordAuthorization: Basic … header (alice:s3cret → Basic YWxpY2U6czNjcmV0)
--oauth2-bearer, -A, -e, -b name=valueAuthorization: Bearer, User-Agent, Referer, Cookie headers
-I, --headHEAD request
-LFollow redirects; without it, the code does not follow them
--url, --url-queryURL and query string; a URL without a scheme gets http://, as curl assumes
-s, -S, -v, -i, -o, -w, --compressedDropped: they only change what curl prints or saves
Any other option, and -kListed in a comment at the top of the code and in the status line. With -k the code keeps TLS verification on

Options can be grouped (-sSL) or have the value attached (-XPUT, -H'X: 1'). An option that curl 8.7 does not have is an error instead of being read as the URL.

Check These Before You Run the Code

  • JavaScript (fetch) runs in a page, which cannot open local paths. File uploads and @file bodies come from an <input type="file">, in the order the comment lists them. fetch also follows redirects, and the browser drops forbidden request headers such as Cookie and Host.
  • Text from name=<file in the JavaScript tab is sent with CRLF line breaks: FormData normalizes line breaks in text values, as the HTML form encoding rules require. Python, Go, PHP, and Node.js send the file text as is.
  • Node.js uses axios, which throws on 4xx and 5xx responses; curl does not. maxRedirects: 0 mirrors curl without -L, so a 3xx response also throws. File uploads use fs.openAsBlob, which needs Node.js 19.8 or later.
  • PHP sends several -F fields with the same name only once, because a PHP array keeps one value per key.
  • Shell syntax such as $VAR, $(...), and pipes is not expanded: "$TOKEN" stays the literal text $TOKEN.

Copy a Request From the Browser

In Chrome or Edge DevTools, open the Network panel, right-click a request, and choose Copy → Copy as cURL (bash). The converter reads the $'...' quoting that this variant uses for values with quotes or line breaks. On Windows, pick the bash variant: the cmd variant uses ^ escapes that this converter does not read. Requests copied this way often contain cookies and tokens; this page does not load analytics or ads, and the conversion runs in your browser.

FAQ

What flags does the converter support?

It reads every option of curl 8.7. Converted: -X, -H, -d / --data / --data-raw / --data-binary / --data-ascii / --data-urlencode, --json, -G, -F / --form-string (including file uploads), -u, --oauth2-bearer, -A, -e, -b, -I, -L, --url, --url-query. Options that only change curl's output (-s, -v, -o, -i, --compressed) are dropped; any other option is listed in a comment at the top of the code.

Does this send my cURL command to a server?

No. All parsing and code generation happen in your browser using JavaScript. Your cURL commands and any secrets they contain never leave your device.

Why does the generated code use 'await'?

The JavaScript (fetch) code runs in the browser console and in ES modules. The Node.js code is an ES module (import axios from 'axios'), where top-level await is allowed; save it as a .mjs file or in a package with "type": "module".

How are Basic Auth credentials handled?

-u user:password becomes an Authorization: Basic header with the UTF-8 bytes of user:password in Base64, as curl sends it. Without a colon curl asks for the password, so -u user is listed as not converted.

What if my cURL command spans multiple lines?

Multi-line cURL commands using backslash line continuation are fully supported. Paste the entire command and the converter will handle the line breaks.