# Getting Started with cURL

# What is cURL ?

**cURL** stands for **Client URL**. cURL is a **command-line tool used to transfer data to or from a server**. It is like a **web browser without a GUI (Graphical User Interface)**. It supports a vast array of protocols, including HTTP, HTTPS, FTP, and SFTP.

* When you type `google.com` in Chrome, the browser sends a request to Google's server and displays the webpage for you.
    
* When you type `curl google.com` in your terminal, cURL sends the same request, but instead of showing the webpage with images and buttons, it just shows the raw code (HTML) directly into your terminal.
    

# Basic Usage (GET Request)

By default, if you provide no arguments other than the URL, cURL performs an HTTP **GET** request and prints the response body to the terminal.

```bash
curl "https://www.example.com"
```

# Why cURL is Used ?

Below are some of the uses of cURL with examples:

### 1\. Testing APIs

Developers frequently use cURL to test backend APIs. It allows you to send specific HTTP methods (GET, POST, PUT, DELETE etc) and see the response.

### 2\. Downloading Files

cURL can be used for downloading files on servers where you don't have a GUI.

### 3\. Debugging Network Issues

Sometimes a website isn't loading, or an API is returning errors. You can use cURL to inspect the HTTP Headers, status codes, cookies, or server information.

### 4\. Scripting and Automation

Since cURL is a command-line tool, it can be embedded into scripts (Bash, Python, etc.).

* **Example:** A script that runs every night to download a backup file, A CI/CD pipeline using cURL to trigger a webhook after a build finishes etc.
    

# Common Arguments That cURL Supports with Examples

### 1\. `-X` or `--request` (Specify HTTP Method)

By default, cURL uses GET. Use `-X` to specify other methods like POST, PUT, DELETE, or PATCH.

* **Example (DELETE):**
    
    ```bash
    curl -X DELETE "https://api.example.com/users/123"
    ```
    

### 2\. `-d` or `--data` (Send Data / POST)

Used to send data to the server. When you use `-d`, cURL automatically sets the method to **POST** (so `-X POST` is optional here) and sets the `Content-Type` to `application/x-www-form-urlencoded`.

* **Example (Form Data):**
    
    ```bash
    curl -d "username=jdoe&password=123" "https://example.com/login"
    ```
    

### 3\. `-H` or `--header` (Custom Headers)

Allows you to send custom HTTP headers. This is essential when sending JSON data (to set `Content-Type`) or authentication tokens.

* **Example (Sending JSON):**
    
    ```bash
    curl -H "Content-Type: application/json" \
         -d '{"key":"value"}' \
         "https://api.example.com/data"
    ```
    

### 4\. `-i` or `--include` (Include HTTP Headers)

By default, cURL only outputs the response body. The `-i` flag includes the HTTP response headers in the output.

* **Example:**
    
    ```bash
    curl -i "https://www.example.com"
    ```
    

### 5\. `-I` or `--head` (Fetch Headers Only)

Fetches only the headers and not the body. This is useful for checking if a server is up or inspecting server metadata (like cache expiry) without downloading the whole page.

* **Example:**
    
    ```bash
    curl -I "https://www.example.com"
    ```
    

### 6\. `-v` or `--verbose` (Verbose Mode)

The most important flag for debugging. It prints the entire conversation: the connection handshake, the request headers sent by you (`>`), and the response headers received from the server (`<`).

* **Example:**
    
    ```bash
    curl -v "https://www.example.com"
    ```
    

### 7\. `-o` and `-O` (Save Output to File)

Instead of printing to the terminal, these flags save the response to a file.

* `-o <filename>` (Lowercase): Saves the output to a specific filename you choose.
    
    ```bash
    curl -o my_image.png "https://example.com/image_12345.png"
    ```
    
* `-O` (Uppercase): Saves the file using the remote filename from the URL.
    
    ```bash
    curl -O "https://example.com/archive.zip"
    # Saves as "archive.zip" locally
    ```
    

### 8\. `-L` or `--location` (Follow Redirects)

By default, cURL does not follow HTTP redirects (status codes 301, 302). If you request a URL that has moved, cURL will just return the "Moved" message. `-L` tells `curl` to follow the redirect to the final destination.

* **Example:**
    
    ```bash
    # google.com redirects to www.google.com
    curl -L "https://google.com"
    ```
    

### 9\. `-u` or `--user` (Authentication)

Used for Basic Authentication. It takes the format `username:password`.

* **Example:**
    
    ```bash
    curl -u admin:secret123 "https://api.example.com/protected"
    ```
    
    Note*:* This encodes the credentials into the `Authorization: Basic ...` header.
    

### 10\. `-k` or `--insecure` (Allow Insecure SSL)

Tells cURL to ignore SSL certificate verification errors. This is often used in development environments with self-signed certificates, but **should not be used in production**.

* **Example:**
    
    ```bash
    curl -k "https://localhost:8080"
    ```
    

### 11\. `-F` or `--form` (Multipart Form Data / File Upload)

Used to upload files via `multipart/form-data`, similar to an HTML `<form>` with a file input.

* **Example:**
    
    ```bash
    curl -F "profile_pic=@/home/user/photo.jpg" "https://example.com/upload"
    ```
    
    Note: The `@` symbol tells curl to read from a file path.
    

# Sample cURL Command in Verbose Mode

Below is the sample output of the cURL command when out type `curl -v https://www.google.com` in your terminal

```bash
curl -v "https://www.google.com"
* Host www.google.com:443 was resolved.
* IPv6: (none)
* IPv4: 142.251.42.228
*   Trying 142.251.42.228:443...
* Connected to www.google.com (142.251.42.228) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=www.google.com
*  start date: Dec 29 19:53:09 2025 GMT
*  expire date: Mar 23 19:53:08 2026 GMT
*  subjectAltName: host "www.google.com" matched cert's "www.google.com"
*  issuer: C=US; O=Google Trust Services; CN=WR2
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://www.google.com/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: www.google.com]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
> GET / HTTP/2
> Host: www.google.com
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/2 200 
< date: Wed, 28 Jan 2026 18:54:08 GMT
< expires: -1
< cache-control: private, max-age=0
< content-type: text/html; charset=ISO-8859-1
< content-security-policy-report-only: object-src 'none';base-uri 'self';script-src 'nonce-UbIt5lEC3SK1NNFlSpaOsw' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
< accept-ch: Sec-CH-Prefers-Color-Scheme
< p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
< server: gws
< x-xss-protection: 0
< x-frame-options: SAMEORIGIN
< set-cookie: __Secure-STRP=AD6DogtDs3AcobeO4nyYf6KL2XiFGV-ZEiQ6CE_Fm9YHy54RJJD7kriwtltE3kzdHbDF-XNg7j9q4UiooHPqJ8smmU3m5IehtFLy; expires=Wed, 28-Jan-2026 18:59:08 GMT; path=/; domain=.google.com; Secure; SameSite=strict
< set-cookie: AEC=AaJma5tio11s3e7lwtzg44TKffbu2JO2eRCH1UEeySC-GiZfH5RR_QO7ig; expires=Mon, 27-Jul-2026 18:54:08 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
< set-cookie: NID=528=FkkkYctqrYxwFDwYM60zFAr0jG0oFMNaFfj_Fc_Zh4W2C4iTqC4tZW1-AINEfDgXm1LBKKmdXY3vefQ6T2UuGehXPgquvX6mFc7jNh50SMrVTwHy7A0xSE5LTEp0x1RY8C5jXLf9DGQY4ivxE4nWEqj0S9goLO2bXajF9dofX__RRYcg8pinVE-bzo1AoQ6uK8fG0IjW4Wza1Qyvzo78x86T-yn9BLb5ywg; expires=Thu, 30-Jul-2026 18:54:08 GMT; path=/; domain=.google.com; HttpOnly
< set-cookie: __Secure-BUCKET=CMcH; expires=Mon, 27-Jul-2026 18:54:08 GMT; path=/; domain=.google.com; Secure; HttpOnly
< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
< accept-ranges: none
< vary: Accept-Encoding
< 
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en-IN"><head><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>Google</title><script>...</script></head><body>...</body></html>
```

#### 1\. The Request (`>`) Section:

This section shows what your computer sent to the server.

* `GET / HTTP/2`: The core command.
    
    * **GET**: The HTTP Method. It tells the server "I want to retrieve/get data."
        
    * **/**: The Path. It tells the server which page or resource you want to access.
        
    * **HTTP/2**: The protocol version being used.
        
* `Host: www.google.com`: This header tells the server which website you are trying to reach.
    
* `User-Agent`: Identifies the client software making the request (in this case, `curl`).
    
* `Accept: */*`: Tells the server that the client is willing to accept any type of content in return.
    

#### 2\. The Response (`<`) Section:

This section shows the data the server sent back.

* `HTTP/2 200`: The Status Line.
    
    * **200**: The Status Code. `200` means "OK" or "Success".
        
* `Content-Type`: Tells the client what kind of data is sent by server. Here, `text/html` means it is a webpage.
    
* `Content-Length`: The size of the response body in bytes.
    
* **The Body**: Everything after the headers (starting with `<!doctype html>`) is the actual content (the HTML code) that a browser would render for you to see.
