Table of contents

What is the Difference Between --data and --json Options in Curl?

When working with HTTP APIs and web scraping, understanding the difference between curl's --data and --json options is crucial for sending POST requests correctly. While both options are used to send data in HTTP requests, they handle content formatting, headers, and encoding differently. This guide explains these differences and provides practical examples for various use cases.

Overview of --data and --json Options

The --data option is curl's traditional method for sending POST data, while --json is a newer convenience option specifically designed for JSON payloads. Understanding when to use each option can save you debugging time and ensure your API requests work as expected.

The --data Option: Traditional Data Sending

The --data (or -d) option sends data as the request body and automatically sets the request method to POST. By default, it uses application/x-www-form-urlencoded content type.

Basic --data Syntax

curl --data "key1=value1&key2=value2" https://api.example.com/endpoint

Key Characteristics of --data

  1. Default Content-Type: Sets Content-Type: application/x-www-form-urlencoded
  2. Data Format: Expects URL-encoded data by default
  3. Method: Automatically changes request method to POST
  4. Manual Headers: Requires manual header setting for JSON content

Examples with --data

Form Data Submission:

curl --data "username=john&password=secret123" \
     https://api.example.com/login

JSON Data with Manual Headers:

curl --data '{"name": "John Doe", "email": "john@example.com"}' \
     --header "Content-Type: application/json" \
     https://api.example.com/users

Reading Data from File:

curl --data @user_data.json \
     --header "Content-Type: application/json" \
     https://api.example.com/users

The --json Option: Modern JSON Convenience

The --json option was introduced in curl 7.82.0 as a convenience feature specifically for JSON data. It automatically handles JSON formatting and sets appropriate headers.

Basic --json Syntax

curl --json '{"key1": "value1", "key2": "value2"}' https://api.example.com/endpoint

Key Characteristics of --json

  1. Automatic Content-Type: Sets Content-Type: application/json
  2. JSON Validation: Validates JSON syntax
  3. Method: Automatically changes request method to POST
  4. Accept Header: Sets Accept: application/json

Examples with --json

Simple JSON POST:

curl --json '{"name": "John Doe", "email": "john@example.com"}' \
     https://api.example.com/users

Complex JSON Structure:

curl --json '{
  "user": {
    "name": "John Doe",
    "preferences": {
      "theme": "dark",
      "notifications": true
    }
  }
}' https://api.example.com/users

JSON from File:

curl --json @user_data.json https://api.example.com/users

Side-by-Side Comparison

| Feature | --data | --json | |---------|--------|--------| | Default Content-Type | application/x-www-form-urlencoded | application/json | | Accept Header | Not set | application/json | | JSON Validation | No | Yes | | Curl Version | All versions | 7.82.0+ | | Primary Use Case | Form data, any content type | JSON APIs |

Practical Examples and Use Cases

API Authentication

Using --data for form-based login:

curl --data "username=admin&password=secret" \
     --cookie-jar cookies.txt \
     https://api.example.com/auth/login

Using --json for token-based authentication:

curl --json '{"username": "admin", "password": "secret"}' \
     https://api.example.com/auth/token

Web Scraping Scenarios

When performing web scraping tasks, you might need to interact with APIs that require different data formats. For instance, when handling authentication in Puppeteer, you might need to make preliminary API calls to obtain session tokens.

Submitting form data for session creation:

curl --data "csrf_token=abc123&user_id=456" \
     --header "X-Requested-With: XMLHttpRequest" \
     https://target-site.com/api/session

Sending JSON configuration for API endpoints:

curl --json '{
  "scraping_config": {
    "wait_for": "networkidle0",
    "viewport": {"width": 1920, "height": 1080}
  }
}' https://scraping-api.example.com/configure

Error Handling and Debugging

Verbose output with --data:

curl --data '{"test": "data"}' \
     --header "Content-Type: application/json" \
     --verbose \
     https://api.example.com/test

Verbose output with --json:

curl --json '{"test": "data"}' \
     --verbose \
     https://api.example.com/test

The --json option provides cleaner output since it automatically sets the correct headers.

Advanced Usage Patterns

Combining with Other curl Options

Using --data with custom headers:

curl --data "action=scrape&url=https://example.com" \
     --header "Authorization: Bearer token123" \
     --header "User-Agent: MyBot/1.0" \
     https://api.example.com/scrape

Using --json with authentication:

curl --json '{"url": "https://example.com", "format": "json"}' \
     --header "Authorization: Bearer token123" \
     https://api.example.com/scrape

File-based Data Submission

Reading form data from file:

echo "name=John&email=john@example.com" > form_data.txt
curl --data @form_data.txt https://api.example.com/submit

Reading JSON from file:

echo '{"name": "John", "email": "john@example.com"}' > user.json
curl --json @user.json https://api.example.com/users

Common Pitfalls and Best Practices

Content-Type Mismatches

Wrong approach - using --data without proper headers for JSON:

# This sends JSON data but with wrong Content-Type
curl --data '{"name": "John"}' https://api.example.com/users

Correct approaches:

# Option 1: Use --json (recommended for JSON)
curl --json '{"name": "John"}' https://api.example.com/users

# Option 2: Use --data with explicit headers
curl --data '{"name": "John"}' \
     --header "Content-Type: application/json" \
     https://api.example.com/users

Special Character Handling

URL encoding with --data:

curl --data "message=Hello%20World%21" https://api.example.com/send

JSON escaping with --json:

curl --json '{"message": "Hello \"World\"!"}' https://api.example.com/send

Performance Considerations

When building web scraping applications that make numerous API calls, consider using connection reuse and HTTP/2 features. This is particularly relevant when monitoring network requests in Puppeteer scenarios where you need to optimize request performance.

# Reuse connections for multiple requests
curl --json '{"batch": "request1"}' \
     --http2 \
     --keepalive-time 30 \
     https://api.example.com/batch

When to Use Each Option

Use --data when:

  • Working with form-based APIs
  • Sending non-JSON data (XML, plain text, binary)
  • Using older curl versions (< 7.82.0)
  • Need precise control over Content-Type headers
  • Submitting URL-encoded form data

Use --json when:

  • Working with modern REST APIs
  • Sending JSON payloads
  • Want automatic header management
  • Need JSON syntax validation
  • Building JSON-heavy applications

Compatibility and Version Considerations

The --json option requires curl 7.82.0 or later. Check your curl version:

curl --version

If you're using an older version, stick with --data and manual header management:

curl --data '{"key": "value"}' \
     --header "Content-Type: application/json" \
     --header "Accept: application/json" \
     https://api.example.com/endpoint

Real-World Integration Examples

Python Integration

When building Python web scrapers, you might need to test API endpoints before implementing them in your scraping code. Here's how both options translate to Python requests:

curl --data equivalent in Python:

import requests

# Form data
response = requests.post(
    'https://api.example.com/login',
    data={'username': 'john', 'password': 'secret123'}
)

# JSON data (manual headers)
response = requests.post(
    'https://api.example.com/users',
    data='{"name": "John Doe", "email": "john@example.com"}',
    headers={'Content-Type': 'application/json'}
)

curl --json equivalent in Python:

import requests

# JSON data (automatic headers)
response = requests.post(
    'https://api.example.com/users',
    json={'name': 'John Doe', 'email': 'john@example.com'}
)

JavaScript/Node.js Integration

Similar principles apply when working with browser automation tools. When handling AJAX requests using Puppeteer, understanding these curl patterns helps you intercept and modify network requests:

Using fetch API with different data formats:

// Form data equivalent to curl --data
const formResponse = await fetch('https://api.example.com/login', {
  method: 'POST',
  headers: {'Content-Type': 'application/x-www-form-urlencoded'},
  body: 'username=john&password=secret123'
});

// JSON equivalent to curl --json
const jsonResponse = await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({name: 'John Doe', email: 'john@example.com'})
});

Conclusion

Both --data and --json options serve important roles in HTTP communication. The --data option provides flexibility for various content types and maintains compatibility across curl versions, while --json offers convenience and automatic header management for JSON-specific use cases. Choose the option that best fits your project requirements, API specifications, and curl version constraints.

Understanding these differences will help you build more reliable web scraping tools and API integrations, whether you're working with simple form submissions or complex JSON APIs. Remember to always test your requests and verify that the receiving API correctly processes your data format and headers.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon