cURL to Code Converter
Convert any cURL command to Python, JavaScript, Go, PHP or Ruby
๐ Your cURL command is never uploaded โ all conversion runs entirely in your browser. Your data never leaves your device.
What is cURL and why do developers use it?
cURL (Client URL) is a command-line tool that sends HTTP requests from a terminal. It ships with macOS and most Linux distributions, and it runs on Windows via WSL or a standalone build. You can use it to GET data from a REST API, POST a JSON body to a webhook, download a file, check HTTP headers, or probe a server for debugging โ all without opening a browser or writing a single line of code.
Almost every API documentation page uses cURL to show how to call an endpoint. Stripe, GitHub, Twilio, OpenAI, AWS โ they all use cURL examples because it is the lowest common denominator: any developer on any operating system can paste the command into a terminal and see a real response immediately. When you click "Copy as cURL" in the Chrome DevTools Network panel or export a request from Postman, you get a cURL command.
The problem is that a working cURL command and production code are two different things. You can verify a request works with cURL in thirty seconds, but you cannot ship a cURL one-liner as part of your Python microservice or your Next.js app. You need to translate the cURL flags and their arguments into the native HTTP client idiom of your language. That translation is mechanical but error-prone โ it is easy to forget a header, misplace a colon, or accidentally double-encode the body.
Converting cURL to Python with the requests library
The Python requests library is the standard way to make HTTP calls in Python. It abstracts away the raw socket work and gives you a clean, readable API that mirrors how you think about HTTP requests.
A simple cURL GET request like curl https://api.example.com/users becomes requests.get('https://api.example.com/users'). Each HTTP method maps to a named function: requests.get(), requests.post(), requests.put(), requests.delete(), and requests.patch().
The -H flags become a Python dictionary passed as the headers= keyword argument. Multiple -H flags merge into a single dictionary. The -d body becomes the data= parameter, which sends the raw string as the request body โ identical to what cURL does. If you want requests to parse the body string as JSON and set the Content-Type header automatically, you would use the json= parameter with a Python dictionary instead, but this converter preserves your original string so you do not have to parse and re-encode it.
Basic authentication from -u username:password maps to auth=('username', 'password'). The requests library handles the Base64 encoding and appends the Authorization header automatically โ no manual encoding needed.
For production code, consider wrapping the call in a requests.Session(). Sessions reuse the underlying TCP connection across multiple requests to the same host, which dramatically reduces latency when making many API calls in sequence. They also let you set shared headers and auth once at the session level rather than repeating them on every call.
Converting cURL to JavaScript fetch
The Fetch API is the native HTTP client built into every modern browser and into Node.js 18+. It uses Promises and pairs naturally with async/await. The generated code wraps the call in an await expression โ remember to place it inside an async function or at the top level of an ES module where top-level await is supported.
cURL headers translate directly to a plain object in the second argument to fetch(). The request body from -d becomes the body: property as a string. For GET requests, the options object is omitted entirely so the output stays as concise as possible.
When the cURL command uses -u username:password basic auth, the converter encodes the credentials with btoa() and adds the resulting Authorization: Basic โฆ header, since fetch does not have a native auth parameter. In Node.js you would replace btoa() with Buffer.from('user:pass').toString('base64') if targeting older Node.js versions that pre-date btoa().
The output calls response.text() to read the body as a string. If you know the response is JSON, replace it with response.json() to get a parsed object directly. You should also add error handling: check response.ok before reading the body, since fetch only rejects the promise on network errors โ a 4xx or 5xx status does not throw automatically.
Converting cURL to Go, PHP, and Ruby
Go uses the net/http package from the standard library โ no third-party dependency required. The generated code creates a *http.Request with http.NewRequest(), sets headers with req.Header.Set(), and executes the request with an http.Client. Go's explicit error handling means each operation that can fail is checked with an if err != nil block. Basic auth is handled by req.SetBasicAuth(), which is cleaner than manually building the Authorization header.
PHP has its own curl extension โ confusingly, the PHP curl_* functions wrap the same underlying libcurl library as the cURL command-line tool, but the API is procedural and very different in style. The generated PHP code initialises a cURL handle with curl_init(), sets options with curl_setopt(), executes with curl_exec(), and closes the handle. CURLOPT_RETURNTRANSFER is always set to true so the response body is returned as a string rather than printed immediately.
Ruby uses the Net::HTTP class from the standard library. The generated code parses the URL with URI.parse(), creates an http object, enables SSL automatically when the URL scheme is https, and instantiates the correct request class (Net::HTTP::Post, Net::HTTP::Get, etc.). Headers are set using hash-bracket notation and basic auth is handled by request.basic_auth().
Common cURL flags explained
Understanding what each flag does helps you predict what the converter will generate โ and helps you write cURL commands that translate cleanly to code.
| Flag | Long form | What it does |
|---|---|---|
| -X METHOD | --request | Sets the HTTP method. Defaults to GET (or POST with -d). |
| -H "K: V" | --header | Adds a request header. Repeat for multiple headers. |
| -d "body" | --data | Sets the request body. Implies POST if -X is not set. |
| --data-raw | Like -d but @ is not treated as a filename prefix. | |
| --data-binary | Like -d but preserves newlines and binary data unchanged. | |
| -u user:pw | --user | HTTP basic authentication. Encoded as Base64 in the Authorization header. |
| -b "c=v" | --cookie | Sends cookies. Becomes a Cookie: header in code. |
| -L | --location | Follow HTTP redirects (3xx). Ignored in code โ handle redirects explicitly. |
| -k | --insecure | Skip TLS certificate verification. Do not use in production code. |
| -s | --silent | Suppress progress output. No code equivalent. |
| -v | --verbose | Print request/response headers. Use your language's logging instead. |
| -I | --head | Send a HEAD request (no body in response). |
Real-world cURL patterns with examples
These are the patterns you will encounter most often when working with REST APIs.
Authenticating with a bearer token
Most modern APIs use OAuth 2 bearer tokens. The token goes in the Authorization header with the Bearer scheme. In practice, you would read the token from an environment variable rather than hardcoding it in your source code:
curl -H "Authorization: Bearer $API_TOKEN" \ https://api.example.com/me
Sending a JSON payload
Combine -X POST, the Content-Type header, and -d with a JSON string. Use single quotes around the JSON body in the terminal so you do not have to escape the double quotes inside:
curl -X POST https://api.example.com/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"product_id": 42, "quantity": 3}'Updating a resource with PUT
PUT replaces a resource entirely. Use PATCH instead when you only want to update specific fields. Both follow the same cURL pattern โ only the -X value changes:
curl -X PATCH https://api.example.com/users/42 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"email": "newemail@example.com"}'Limitations and edge cases
This converter handles the vast majority of real-world cURL commands, but a few patterns are deliberately outside its scope:
- โขMultipart form data (
-F) โ The-F field=@filepattern for uploading files produces amultipart/form-databody. Each language handles this differently (Python usesfiles=, Go usesmultipart.Writer) and the conversion requires knowing the actual file content. This tool does not support file upload conversion. - โขURL-encoded form data (
--data-urlencode) โ This flag percent-encodes a specific field value before appending it to the body. The converter treats it as raw data, so the encoding step is not replicated in the output. - โขReading body from a file (
-d @file) โ When a data argument starts with@, cURL reads the body from the named file. This tool cannot read your local filesystem, so the literal string@filenameis used as the body value instead. Use--data-rawinstead of-dwith inline JSON to avoid this ambiguity. - โขClient certificates and proxy authentication โ Flags like
--cert,--cacert, and--proxyare silently ignored. Each language handles mTLS and proxies through its own configuration mechanism that requires file paths and additional setup not expressible in a simple conversion.