Guides

How to Convert cURL Commands to Python and JavaScript Fetch

To convert cURL commands to Python or JavaScript, extract command-line flags like -X for HTTP methods, -H for headers, -d for payloads, and -u for authentication. Map target URLs into Python requests or httpx calls, or JavaScript fetch and axios options objects using our in-browser cURL Converter.

cURL (Client URL) is the universal command-line standard for testing REST APIs, downloading remote assets, and debugging network requests. Developers frequently copy raw cURL commands from API documentation, terminal histories, or web browser DevTools network logs. However, integrating these command-line calls into application codebases requires translating CLI flags into native programming language syntax.

Manually converting cURL syntax into programming code is time-consuming and error-prone. Misconfigured header dictionaries, improper JSON serialization, missing authentication tokens, or incorrect URL parameter escaping can break API integration. This technical master guide provides an end-to-end framework for parsing cURL options and translating them into production-ready Python (requests, httpx) and JavaScript (fetch, axios) code.

Key Definitions: cURL, HTTP Requests, Request Headers, Authentication, Python requests, and Fetch API

Converting command-line web requests into software code requires a solid understanding of fundamental network protocols and language abstractions:

  • cURL (Client URL): A command-line tool and cross-platform library (libcurl) created by Daniel Stenberg for transferring data over protocols such as HTTP, HTTPS, FTP, and SFTP using URL syntax.
  • HTTP Request: A structured client-to-server message containing a request line (HTTP verb like GET, POST, PUT, DELETE), target URI path, protocol version, request headers, and optional body payload.
  • Request Headers: Key-value metadata pairs sent alongside an HTTP request that define media type preferences (Content-Type, Accept), client identification (User-Agent), authentication context (Authorization), and caching behavior.
  • Bearer Authentication: An HTTP authorization scheme relying on bearer tokens (such as OAuth 2.0 access tokens or JSON Web Tokens / JWTs) formatted inside request headers as Authorization: Bearer <token>.
  • Python requests & httpx: De-facto standard Python HTTP client libraries. requests offers a synchronous, human-friendly API, while httpx delivers modern async/await execution alongside HTTP/2 support and full API compatibility with requests.
  • Fetch API & Axios: The Web standard Promise-based browser interface (window.fetch) and the popular cross-platform HTTP client library (axios) used for asynchronous HTTP requests in JavaScript and Node.js environments.

Anatomy of a cURL Command: Flags, Parameters, and Options

A cURL command consists of the binary invocation (curl), one or more option flags, and a target destination URL. Understanding how cURL parses flags is essential for mapping command-line syntax into code parameters.

Consider a standard cURL POST request with custom headers, basic authentication, and JSON data:

curl -X POST "https://api.example.com/v1/users" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     -u "admin_user:secret_pass123" \
     -d '{"name": "Sarah Connor", "role": "engineer"}'

Core cURL Option Flags Explained

cURL supports short flags (prefixed with a single dash -) and long options (prefixed with double dashes --). The table below lists primary flags and their HTTP protocol equivalents:

Short Flag Long Flag HTTP Component / Function Description
-X --request HTTP Method Specifies the custom HTTP request method (e.g., GET, POST, PUT, PATCH, DELETE).
-H --header Request Header Adds an HTTP header line to the request. Can be specified multiple times for multiple headers.
-d --data Request Body Sends specified data in a POST request. Sets default Content-Type to application/x-www-form-urlencoded if unassigned.
--data-raw --data-raw Request Body Sends data without interpreting the leading @ symbol as a local file path upload directive.
-u --user Authorization Header Passes server authentication details (username:password), encoding them into a Base64 Basic Auth header.
-F --form Multipart Form Data Submits HTTP multipart form data (multipart/form-data), commonly used for file uploads (-F "file=@/path/to/doc.pdf").
-L --location Redirect Follow Forces cURL to follow HTTP 3xx server redirect responses automatically.
-k --insecure SSL/TLS Context Allows insecure connections by disabling SSL/TLS certificate validation checks.
-b --cookie Cookie Header Passes cookie string key-value pairs (name=val) or reads cookies from a local file.

Converting cURL Flags to Python `requests` and `httpx` Code

Translating a cURL command into Python requires mapping CLI arguments into dictionary structures and keyword arguments within the requests or httpx libraries.

1. Mapping HTTP Methods

In Python requests, HTTP methods map directly to convenience functions (requests.get(), requests.post(), requests.put(), requests.delete()) or the generic requests.request(method, url) signature.

2. Header Dictionaries

Each -H "Key: Value" flag in cURL becomes an entry in a Python dictionary. Header names must be formatted as string keys, retaining their exact casing:

headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer eyJhbGciOiJIUzI1Ni...'
}

3. Data Payloads: json vs data Keyword Arguments

Python requests distinguishes between raw body text and JSON structures:

  • json=payload_dict: Use when the payload is valid JSON and cURL contains -H "Content-Type: application/json". Python automatically converts the dict into a JSON string via json.dumps() and appends the Content-Type: application/json header.
  • data=raw_string or data=form_dict: Use when sending URL-encoded form data (-d "param1=val1&param2=val2") or raw unformatted plain text payloads.

Side-by-Side Python Conversion Example

Take this complex cURL request featuring custom headers, query parameters, bearer auth, and JSON body data:

curl -X PUT "https://api.example.com/v2/items?category=books&sort=asc" \
     -H "Authorization: Bearer secret_token_99" \
     -H "Content-Type: application/json" \
     -d '{"title": "Automated Data Mining", "price": 49.99, "in_stock": true}'

Converted to synchronous Python requests:

import requests

url = "https://api.example.com/v2/items"

params = {
    "category": "books",
    "sort": "asc"
}

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

json_data = {
    "title": "Automated Data Mining",
    "price": 49.99,
    "in_stock": True
}

response = requests.put(url, headers=headers, params=params, json=json_data)

print(f"Status Code: {response.status_code}")
print(response.json())

Converted to asynchronous Python httpx:

import httpx
import asyncio

async def update_item():
    url = "https://api.example.com/v2/items"
    params = {"category": "books", "sort": "asc"}
    headers = {"Authorization": "Bearer secret_token_99"}
    json_data = {"title": "Automated Data Mining", "price": 49.99, "in_stock": True}

    async with httpx.AsyncClient() as client:
        response = await client.put(url, headers=headers, params=params, json=json_data)
        print(f"Status: {response.status_code}")
        return response.json()

asyncio.run(update_item())

Converting cURL Flags to JavaScript `fetch` and Node.js `axios`

JavaScript processes HTTP calls asynchronously using Promises. Converting cURL commands to JavaScript requires building an options object passed to fetch() or configuring an axios request config object.

1. Browser Fetch API (`window.fetch`) Syntax

The standard fetch(url, options) method accepts a URL string and an optional options object defining HTTP properties:

const response = await fetch('https://api.example.com/v1/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  body: JSON.stringify({ key: 'value' })
});
const data = await response.json();

2. Handling Body Serialization in JavaScript

Unlike Python requests, native JavaScript fetch does not automatically serialize JSON objects. You must explicitly call JSON.stringify() on your object before assigning it to the body property.

For URL-encoded form data (-d "foo=bar&baz=qux"), use the native URLSearchParams API:

const bodyParams = new URLSearchParams();
bodyParams.append('foo', 'bar');
bodyParams.append('baz', 'qux');

const response = await fetch(url, {
  method: 'POST',
  body: bodyParams
});

Side-by-Side JavaScript Conversion Example

Consider a cURL request with Basic Authentication and form data:

curl -X POST "https://api.example.com/v1/oauth/token" \
     -u "client_id_123:client_secret_xyz" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "grant_type=client_credentials&scope=read_write"

Converted to native JavaScript fetch (Browser & Node.js 18+):

async function getAccessToken() {
  const url = 'https://api.example.com/v1/oauth/token';
  
  // Base64 encode basic credentials for HTTP Authorization header
  const credentials = btoa('client_id_123:client_secret_xyz');
  
  const headers = {
    'Authorization': `Basic ${credentials}`,
    'Content-Type': 'application/x-www-form-urlencoded'
  };

  const body = new URLSearchParams({
    'grant_type': 'client_credentials',
    'scope': 'read_write'
  });

  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: headers,
      body: body
    });

    if (!response.ok) {
      throw new Error(`HTTP Error! Status: ${response.status}`);
    }

    const data = await response.json();
    console.log('Token Payload:', data);
  } catch (error) {
    console.error('Fetch Error:', error);
  }
}

getAccessToken();

Converted to Node.js axios:

const axios = require('axios');

async function getAccessTokenAxios() {
  const config = {
    method: 'post',
    url: 'https://api.example.com/v1/oauth/token',
    auth: {
      username: 'client_id_123',
      password: 'client_secret_xyz'
    },
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    data: new URLSearchParams({
      grant_type: 'client_credentials',
      scope: 'read_write'
    }).toString()
  };

  try {
    const response = await axios.request(config);
    console.log('Response Data:', response.data);
  } catch (error) {
    console.error('Axios Error:', error.response ? error.response.data : error.message);
  }
}

getAccessTokenAxios();

How to Copy cURL Commands from Chrome, Firefox, and Edge DevTools

Modern browser Developer Tools allow developers to capture live network requests generated by web applications and export them as exact cURL commands.

Follow these steps to extract cURL syntax from your browser:

  1. Open Developer Tools: Press F12 or Ctrl + Shift + I (Windows/Linux) or Cmd + Option + I (macOS) in Google Chrome, Mozilla Firefox, Microsoft Edge, or Apple Safari.
  2. Navigate to the Network Tab: Click the Network tab at the top of the DevTools panel. Ensure the recording indicator (red dot) is active.
  3. Trigger the Target Network Event: Interact with the web application (e.g., submit a web form, click a button, or reload the page) to generate the target API call.
  4. Locate and Right-Click the Network Request: Find the target request line in the Network panel log. Right-click the entry.
  5. Copy as cURL Syntax:
    • In Chrome / Edge: Hover over Copy $\rightarrow$ select Copy as cURL (bash) or Copy as cURL (POSIX). Avoid “cmd” syntax unless executing strictly in Windows Command Prompt.
    • In Firefox: Hover over Copy $\rightarrow$ click Copy as cURL.
    • In Safari: Right-click $\rightarrow$ select Copy as cURL.

Cleaning Up Copied DevTools cURL Commands

Browser DevTools export cURL commands containing browser-specific headers, such as sec-ch-ua, accept-language, sec-fetch-dest, and cookie headers. When importing copied cURL commands into code scripts, strip out non-essential browser headers to keep your Python or JavaScript code clean, concise, and maintainable.

How to Convert cURL to Code Privately in Your Browser (Step-by-Step)

EasyExtract provides a privacy-first, client-side cURL conversion engine that transforms complex command-line syntax into clean code instantly inside your browser without sending your data to external servers.

  1. Obtain Your Raw cURL Command: Copy your cURL command string from browser DevTools, API documentation, or terminal history.
  2. Launch EasyExtract cURL Converter: Open the EasyExtract cURL Converter tool in any modern web browser.
  3. Paste Syntax into Input Terminal: Paste your cURL command into the text input area. The client-side Abstract Syntax Tree (AST) parser validates flags in real time.
  4. Select Target Code Framework: Choose your desired target language output:
    • Python: requests, httpx, or aiohttp
    • JavaScript: Browser fetch(), Node.js axios, or XMLHttpRequest
    • Additional Languages: Go (net/http), PHP (curl_exec / Guzzle), Java (HttpClient), or Rust (reqwest)
  5. Copy Formatted Source Code: Review the auto-formatted headers dictionary, query parameter object, and body serialization code. Click Copy Code to paste directly into your IDE.

Because EasyExtract processes all cURL parsing locally using WebAssembly and client-side JavaScript, sensitive API keys, authorization tokens, passwords, and private endpoint URLs never leave your device memory.

Frequently Asked Questions

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

The -d (or --data) flag sends HTTP POST data, stripping newline characters and treating leading @ characters as file upload instructions (e.g., -d @data.json reads from a file). The --data-raw flag prevents cURL from interpreting the @ symbol as a file path, ensuring literal strings starting with @ are passed as raw text. The --data-binary flag posts binary data exactly as specified, preserving all embedded carriage returns, line breaks, and whitespace without modification.

How does cURL handle JSON payloads compared to form-urlencoded data?

By default, cURL’s -d flag sets the HTTP Content-Type header to application/x-www-form-urlencoded. To transmit JSON payloads, you must explicitly pass a custom content type header using -H "Content-Type: application/json" along with your formatted JSON string payload (e.g., -d '{"key":"value"}'). When converting to Python, JSON payloads map to the json={} kwarg, whereas form data maps to data={}.

Why does my converted Python or JavaScript fetch request fail with a 403 Forbidden error?

A 403 Forbidden error usually occurs because the target server relies on specific HTTP request headers for anti-bot protection or browser identification. Browser DevTools copy cURL commands with headers like User-Agent, Referer, Accept, and Origin. If your converted code omits these headers, security layers like Cloudflare or AWS WAF may block the programmatic request. Ensure all required browser headers and cookies are included in your request code.

How do I pass Bearer tokens and Basic Auth headers when converting cURL commands?

In cURL, Bearer tokens are passed using -H "Authorization: Bearer <token>", which translates directly into header dictionaries in Python (headers={'Authorization': 'Bearer '}) and JavaScript. Basic Authentication uses -u "username:password". When converting to code, Python requests handles this via auth=('username', 'password'), while JavaScript native fetch requires Base64 encoding: 'Authorization': 'Basic ' + btoa('username:password').

What is the best way to convert cURL commands containing file uploads (-F / –form)?

cURL’s -F or --form flag constructs an HTTP multipart/form-data POST payload. In Python requests, file uploads map to the files parameter using open file handles: files={'file': open('doc.pdf', 'rb')}. In modern JavaScript environments, multipart form uploads map to the native FormData class, appending files using formData.append('file', fileInput.files[0]).

Is it safe to convert cURL commands containing API keys or password tokens online?

Converting cURL commands on cloud-based web tools that process syntax on remote servers exposes secret API tokens, passwords, and private endpoint URLs to server logs and third-party tracking. Using EasyExtract’s 100% client-side cURL Converter guarantees total privacy because parsing and code generation occur entirely in your local browser sandbox without transmitting data across the network.

Can I convert cURL commands to async Python (httpx / aiohttp) and modern JS async/await?

Yes. cURL commands capture stateless HTTP metadata (methods, endpoints, headers, payloads) independent of execution model. In Python, the parsed request parameters can be passed into synchronous requests methods or asynchronous httpx.AsyncClient() / aiohttp.ClientSession() calls. In JavaScript, request configurations seamlessly integrate with modern async/await functions wrapped in try...catch blocks.

Explore our suite of technical guides and in-browser data extraction utilities:

Sources & References

About Md Rejon M

"Md Rejon M. is a premier Data Architecture Specialist and the visionary Lead Engineer behind EasyExtract. With over a decade of hands-on expertise in automation, web scraping, and document parsing, Rejon has dedicated his career to making data extraction fast, accessible, and secure. He designed EasyExtract’s unique serverless infrastructure, ensuring that all tools run 100% locally as client-side JavaScript within the user's browser. By engineering a framework where confidential contracts, client lists, and documents never touch an external server, Rejon has set a new standard for private-by-design utility tools. His deep knowledge of regular expressions, PDF structural layout parsing, and file archive decoding ensures the platform delivers pristine, deduplicated data without compromising user privacy.

Keep reading