cURL to Code Converter

Paste a cURL command and get fetch(), Python requests, or Node axios code — instantly.

cURL Command

Generated Code

Convert a cURL Command to Working Code

Copying a request as cURL from Chrome DevTools, Postman, or an API's documentation is the fastest way to capture exactly what a request looked like — but then you still have to translate it into whatever language your app is written in. This free tool does that translation for you: paste a cURL command and get equivalent fetch(), Python requests, or Node axios code, ready to drop into your project.

How It Works

  • Paste your cURL command into the left editor, or click Sample to try an example login request.
  • Click Convert (or just keep typing — it converts automatically) to parse the method, URL, headers, body, and auth.
  • Switch tabs to see the same request as fetch(), Python requests, or Node axios code.
  • Copy or download the generated code directly into your project (request.js or request.py).

What's Supported

The converter understands the flags that show up in real-world cURL commands: -X/--request for the HTTP method, -H/--header for headers, -d/--data/--data-raw for the request body (including JSON bodies, which get converted to a proper object literal or dict), -u/--user for Basic Auth, -b/--cookie, -F/--form for multipart form uploads, and -G for converting data into query parameters. Multi-line commands copied from DevTools (with trailing \ line continuations) are handled automatically. If a request body is itself a JSON payload you want as typed models, JSON to Code turns it into TypeScript, Python, or Go types.

The complete list, read from the converter's code:

cURL flagWhat the converter does
-X, --requestmethod, upper-cased (-X patch gives PATCH)
-H, --headerheaders, name and value split at the first colon; a header with no colon gets an empty value
-d, --data, --data-raw, --data-ascii, --data-binaryrequest body; several are joined with &; valid JSON becomes an object
-G, --getmoves the -d data into the query string, percent-encoding each key and value
-I, --headmethod HEAD
-u, --userBasic Auth (user:password); ignored if you also give an Authorization header
-F, --formmultipart fields (name=value, and name=@file for a file)
-b, --cookie, -A, --user-agent, -e, --refereradded as Cookie, User-Agent and Referer headers
--urlthe URL (a bare argument also works)
-k, -L, --compressed, -s, -v, -i, -N, -f (and long forms)read and ignored
-o, -x, -m, --connect-timeout, -w, -T (and long forms)read together with their value and ignored

The HTTP method is chosen like this:

Command hasMethod
-X giventhat method
-IHEAD
-GGET (the data goes to the URL)
-d or -F and no -XPOST
nothing elseGET

How Headers, Bodies and Auth Are Mapped

Headers are copied with their original name and case. Bodies that parse as JSON become an object in every language: a JSON.stringify({...}) call in fetch(), a payload = {...} dict sent with json=payload in Python (with true, false and null written as True, False and None), and a data: {...} object in axios, which sends it as JSON. Any other body is kept as a string, and Python sends it with data=. For JSON bodies the generated code leaves the Content-Type header out, because Python and axios set it themselves. fetch() does not: a string body is sent as text/plain, so with fetch() you must add "Content-Type": "application/json" to the headers yourself, as in Example 1 below, where it is missing from the output.

Authentication has three paths. -u user:pass becomes "Authorization": "Basic " + btoa("user:pass") in fetch(), auth=("user", "pass") in Python and auth: { username, password } in axios. An Authorization header you pass with -H (Bearer tokens, API keys) is copied as it is, and if a command has both, the header wins and -u is dropped. Because btoa() only handles Latin-1 text, a password with other characters makes the fetch() version throw; build that header with the Base64 encoder, which handles UTF-8. Cookies, User-Agent and Referer are added as ordinary headers; browsers refuse to let fetch() set some of them (Cookie and Referer among them), while Node and Python can.

Worked Examples in All Three Languages

Every command and output below was produced by running the live converter, character for character.

Example 1: a JSON login request (this is the page's Sample button)

curl -X POST https://api.example.com/v1/login \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{"username":"ada","password":"s3cret"}'

fetch()

fetch("https://api.example.com/v1/login", {
  method: "POST",
  headers: {
    "Accept": "application/json"
  },
  body: JSON.stringify({
    "username": "ada",
    "password": "s3cret"
  }),
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error("Error:", error));

Python requests

import requests

url = "https://api.example.com/v1/login"

payload = {
    "username": "ada",
    "password": "s3cret"
}

headers = {
    "Accept": "application/json",
}

response = requests.post(url, headers=headers, json=payload)
print(response.status_code)
print(response.json())

Node axios

const axios = require('axios');

axios({
  method: "post",
  url: "https://api.example.com/v1/login",
  headers: {
    "Accept": "application/json"
  },
  data: {
    "username": "ada",
    "password": "s3cret"
  },
})
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

Look at what changed. The JSON body became a real object, the Content-Type header disappeared (fine in Python and axios, but add it back in fetch()), the -X POST became the library's POST call, and the generated code ends by printing the parsed JSON response.

Example 2: Basic Auth, query data with -G and an Accept header

curl -u ada:s3cret -G https://api.example.com/search -d "q=hello world" -d page=2 -H 'Accept: application/json'

fetch()

fetch("https://api.example.com/search?q=hello%20world&page=2", {
  method: "GET",
  headers: {
    "Accept": "application/json",
    "Authorization": "Basic " + btoa("ada:s3cret")
  },
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error("Error:", error));

Python requests

import requests

url = "https://api.example.com/search?q=hello%20world&page=2"

headers = {
    "Accept": "application/json",
}

response = requests.get(url, headers=headers, auth=("ada", "s3cret"))
print(response.status_code)
print(response.json())

Node axios

const axios = require('axios');

axios({
  method: "get",
  url: "https://api.example.com/search?q=hello%20world&page=2",
  headers: {
    "Accept": "application/json"
  },
  auth: { username: "ada", password: "s3cret" },
})
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

Here -G turned the two -d values into ?q=hello%20world&page=2, the space written as %20 (see the URL encoder for the rules), no body is sent, and the Basic Auth credentials went to each library's own option.

Example 3: a multipart upload with -F

curl -X POST https://api.example.com/upload -F 'title=My file' -F 'file=@photo.jpg' -H 'X-Api-Key: abc123'

fetch()

const formData = new FormData();
formData.append("title", "My file");
formData.append("file", /* File object */ "photo.jpg");

fetch("https://api.example.com/upload", {
  method: "POST",
  headers: {
    "X-Api-Key": "abc123"
  },
  body: formData,
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error("Error:", error));

Python requests

import requests

url = "https://api.example.com/upload"

files = {
    "title": (None, "My file"),
    "file": open("photo.jpg", "rb"),
}

headers = {
    "X-Api-Key": "abc123",
}

response = requests.post(url, headers=headers, files=files)
print(response.status_code)
print(response.json())

Node axios

const axios = require('axios');

const FormData = require('form-data');
const form = new FormData();
form.append("title", "My file");
form.append("file", fs.createReadStream("photo.jpg"));

axios({
  method: "post",
  url: "https://api.example.com/upload",
  headers: {
    ...form.getHeaders(),
    "X-Api-Key": "abc123"
  },
  data: form,
})
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

Multipart forms need care. In fetch() the file field is only a placeholder: /* File object */ "photo.jpg" is a string, so replace it with a File from an <input type="file">. In Python, open("photo.jpg", "rb") works if the file is next to your script. In axios, the code uses fs.createReadStream but does not require('fs'), and it needs the form-data package, so add const fs = require('fs'); and install it with npm install form-data.

Common Mistakes When Pasting from DevTools

  • Copying the Windows (cmd) variant. Chrome on Windows offers "Copy as cURL (cmd)" with ^ escapes, which this tool does not understand. Choose "Copy as cURL (bash)" instead.
  • Bash copies with $'...'. When a body has line breaks or non-ASCII characters, the bash variant wraps it as $'...'. The converter does not handle that quoting and leaves a stray $ in the body. Remove the $ and write the escape sequences out by hand, or paste the body into the JSON unescape tool first.
  • Leaving every browser header in. DevTools copies origin, referer, user-agent, accept-language, sec-* headers and cookies. Most are noise in a script, some are refused by fetch(), and the cookie and authorization values are secrets, so remove what you do not need.
  • Trusting the method. -XDELETE without a space becomes a GET. Check the method line in the output.
  • Large numbers in JSON bodies. A body value such as 12345678901234567890 is parsed as a JavaScript number first and comes out as 12345678901234567000. Send big IDs as strings.
  • Assuming the response is JSON. All three outputs parse the response as JSON. That fails for HEAD, 204 responses and HTML pages.
  • Sharing the output. Tokens and cookies from the cURL command are copied into the code. Replace them with environment variables before committing it.

What Is Not Supported

These are the limits we found by testing the live converter with real command variations:

Not supported or differentWhat happens
Other languagesOnly fetch(), Python requests and Node axios are generated. There is no Go, PHP, Java, C#, Ruby or shell output.
-XPOST, -XDELETE (no space)Combined short flags are ignored. curl -XDELETE https://api.example.com/x produces a GET; the method is only inferred from -d/-F. Write -X DELETE with a space.
--header='Accept: json'The --flag=value spelling is not recognised; the header is dropped.
-d @body.json, --data-binary @fileThe file is not read. The body becomes the literal text @body.json.
--data-urlencodeTreated like -d: the value is not percent-encoded.
$'...' quotingThe leading $ is kept inside the value and escape sequences such as \n are not interpreted.
Windows cmd style (^ escapes)Not understood; the body keeps the caret characters.
Shell variables, such as $TOKENNot expanded; the text $TOKEN is copied as it is.
Flags with a value that are not on the list above, such as --retry 3The flag is ignored, but if it comes before the URL its value is taken for the URL: curl --retry 3 https://example.com/ fails with "3" doesn't look like a valid URL. Put the URL first.
Several URLsOnly the first URL is used.
Redirects, timeouts, proxies, TLS options, retriesIgnored, so the generated code uses its library's defaults.
Reading the responseThe generated code always calls response.json() (or .json() in Python). A HEAD request, an empty body or an HTML answer will make that line fail; change it to .text() or drop it.

If a command uses something from this list, convert it first as far as the tool allows and then correct the generated code by hand, or fix the command (for example with a space after -X) and convert again.

Privacy

Parsing and code generation happen entirely in your browser using JavaScript. Your cURL command — which often contains auth tokens, cookies, or API keys — is never uploaded to a server.

cURL to Code — Options Explained

Here's what each output format is best suited for, and how the converter handles common cURL patterns.

fetch()

The built-in browser (and modern Node) HTTP client. No dependency to install — ideal for frontend code, browser extensions, or quick scripts. JSON bodies are serialized with JSON.stringify(); add the Content-Type: application/json header yourself.

Python requests

The de facto standard HTTP library for Python. JSON bodies use the json= parameter (so requests sets the Content-Type for you), and Basic Auth maps to the native auth=(user, pass) tuple.

Node axios

A popular promise-based HTTP client for Node.js and the browser. Generated code uses axios's config-object call style, with a dedicated auth option for Basic Auth credentials.

JSON Body Detection

If your -d payload is valid JSON, it's converted into a real object/dict literal (not just a string) in every output format, so the generated code stays readable and editable.

Who Uses This Tool?

Frontend Developers

Copy a request as cURL from the Network tab in DevTools, then instantly get the equivalent fetch() call to reproduce it in your app.

Backend & API Developers

Turn an API's cURL example from its documentation into working Python or Node code without hand-translating headers and body by hand.

QA & Automation Engineers

Convert a cURL command captured from a bug report or Postman collection into a Python script for a test suite.

Students & Learners

See how the same HTTP request looks across three different clients — a fast way to learn the request/response patterns of a new language or library.

Frequently Asked Questions

Where do I get a cURL command to convert?

In Chrome or Firefox DevTools, open the Network tab, right-click any request, and choose "Copy as cURL". Postman also has a "Code" button on any request that can export it as cURL.

Does it support multi-line cURL commands?

Yes. Commands copied from DevTools often span multiple lines with a trailing backslash (\) at the end of each line — the converter automatically joins these into a single command before parsing.

Does it handle authentication?

Yes, for the common cases: -u user:pass (Basic Auth) is converted to each language's native auth mechanism, and an Authorization header from -H is passed through as-is, whatever scheme it uses (Bearer, API key, etc.).

What happens to flags it doesn't recognize?

Flags that don't affect the generated HTTP call — like -k/--insecure, -L/--location, -v/--verbose, or --compressed — are safely ignored rather than causing a parse error. A flag the tool does not know that takes a value, such as --retry 3, is also ignored, but when it comes before the URL its value can be mistaken for the URL.

Is my cURL command uploaded anywhere?

No. All parsing and code generation happens locally in your browser with JavaScript. This matters since cURL commands often contain auth tokens, session cookies, or API keys you don't want to send to a third party.

Can it convert the code back to cURL?

Not currently — this tool converts cURL to code, one direction only. If you need to inspect or format the JSON body of a request, try the JSON Formatter.

Which languages can it generate?

Three: JavaScript fetch(), Python requests and Node axios. There is no Go, PHP, Java, C# or Ruby output. For typed models of a JSON body in more languages, use the JSON to code generator.

Why does my pasted cURL command give a wrong result?

The usual causes are the Windows (cmd) copy with ^ escapes, bash bodies written as $'...', a method written without a space such as -XDELETE, a body read from a file with @file, and a value-taking flag before the URL. Use "Copy as cURL (bash)", put a space after -X and check the generated method and body.

Related Tools

Built by Deepak Kumar — a developer who wanted a JSON tool that respects your privacy. All processing happens in your browser. Your data never leaves your device.