Skip to the content.

Tutorial 2: What is curl?

What is curl and how do curl commands work in C#? curl is the command-line tool that almost every API’s documentation uses for its examples, and CurlDotNet lets you run those same curl commands from C# with Curl.ExecuteAsync. This tutorial explains the tool, its most common options, and how it maps to CurlDotNet.

What You’ll Learn

Prerequisites

The Big Picture

What is curl?

curl is a command-line tool for transferring data to and from servers. Think of it as a web browser without the graphics: you type a URL (plus options) and it prints what the server sent back.

Real-World Analogy

Imagine ordering a pizza:

curl is:

Why curl is Everywhere

1. API Documentation Uses curl

When you read API documentation from GitHub, Stripe, or almost any web service, the examples are curl commands:

# GitHub API
curl https://api.github.com/users/octocat

# Stripe API
curl https://api.stripe.com/v1/charges \
  -u sk_test_KEY: \
  -d amount=2000

2. Developers Use It Every Day

Understanding curl Commands

A typical curl command:

curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer token123" \
  -d '{"name":"Alice","email":"alice@example.com"}'

Breaking It Down

Part What It Does
curl The command name
-X POST Use the POST method (like submitting a form)
https://httpbin.org/post Where to send the request
-H "..." Add a header (extra information)
-d '...' The data to send

Common curl Options

Option What It Does Example
-X HTTP method -X POST, -X PUT
-H Add header -H "Authorization: Bearer token"
-d Send data -d '{"key":"value"}'
-o Save output to file -o result.json
-u Username and password -u user:pass
-L Follow redirects -L
-v Verbose (show details) -v
-k Skip SSL verification -k (testing only)
-i Include response headers in output -i

All of these options work in CurlDotNet. See the curl CLI compatibility reference for the full list.

Common curl Examples

Example 1: Get a Web Page

curl https://httpbin.org/html

Fetches the HTML, like viewing a page’s source in your browser.

Example 2: Get JSON Data

curl https://api.github.com/users/octocat

Gets user data in JSON format, which is what mobile apps do behind the scenes.

Example 3: Send Data to an API

curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -d '{"message":"Hello World"}'

Example 4: Download a File

curl -o image.png https://httpbin.org/image/png

Like right-clicking and choosing “Save As” in a browser.

Example 5: Authentication

curl -u username:password https://httpbin.org/basic-auth/username/password

Sends a username and password using HTTP Basic authentication.

From curl to CurlDotNet

The Problem

You find the right curl command in API documentation:

curl -X POST https://httpbin.org/post \
  -H "Authorization: Bearer token123" \
  -d '{"name":"Alice"}'

But you are writing a C# application. Traditionally you would have to understand what the command does, translate it to HttpClient calls, wire up headers and data separately, and then test that your translation behaves the same way.

The Solution: CurlDotNet

With CurlDotNet you paste the curl command into C#:

using CurlDotNet;

var result = await Curl.ExecuteAsync(@"
    curl -X POST https://httpbin.org/post \
      -H 'Authorization: Bearer token123' \
      -d '{""name"":""Alice""}'
");

Console.WriteLine(result.StatusCode);

No translation step. The leading curl word is optional and backslash line continuations are fine.

How CurlDotNet Works

Not a Wrapper

CurlDotNet does not run curl.exe behind the scenes and does not need curl installed.

Pure .NET Implementation

CurlDotNet is written in C#. It:

  1. Parses the curl command syntax
  2. Maps curl options to HTTP settings
  3. Sends the request with .NET’s own HTTP stack
  4. Returns a CurlResult with the status code, headers, and body

What You Get

curl vs CurlDotNet Comparison

Feature curl (command line) CurlDotNet
Parse responses Manual result.ParseJson<T>()
Error handling Exit codes C# exceptions carrying the same exit code (ex.CurlErrorCode), plus result.StatusCode
Type safety None C# types
IntelliSense None Yes
Integration Shell scripts Any .NET application
Async support No async/await

Real-World Scenarios

Scenario 1: Testing an API

With curl:

curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -d '{"test":true}'

With CurlDotNet in a C# test:

var result = await Curl.ExecuteAsync(@"
    curl -X POST https://httpbin.org/post \
      -H 'Content-Type: application/json' \
      -d '{""test"":true}'
");

Assert.Equal(200, result.StatusCode);
using var echo = System.Text.Json.JsonDocument.Parse(result.Body);
Assert.True(echo.RootElement.GetProperty("json").GetProperty("test").GetBoolean());

Scenario 2: Building an Integration

Found in API docs (Stripe example):

curl https://api.stripe.com/v1/charges \
  -u sk_test_KEY: \
  -d amount=2000 \
  -d currency=usd

Used in your C# app with values filled in:

var charge = await Curl.ExecuteAsync($@"
    curl https://api.stripe.com/v1/charges \
      -u {apiKey}: \
      -d amount={amount} \
      -d currency={currency}
");

if (charge.IsSuccess)
{
    using var data = System.Text.Json.JsonDocument.Parse(charge.Body);
    Console.WriteLine($"Charge id: {data.RootElement.GetProperty("id")}");
}

Scenario 3: Migrating Bash Scripts

Old bash script:

#!/bin/bash
for user in $(cat users.txt); do
  curl -X POST https://httpbin.org/post -d "user=$user"
done

New C# version:

var users = await File.ReadAllLinesAsync("users.txt");

foreach (var user in users)
{
    await Curl.ExecuteAsync($"curl -X POST https://httpbin.org/post -d 'user={user}'");
}

Understanding curl Options in Depth

HTTP Methods

curl -X GET https://httpbin.org/get           # Read data
curl -X POST https://httpbin.org/post         # Create new
curl -X PUT https://httpbin.org/put           # Update entire
curl -X PATCH https://httpbin.org/patch       # Update partial
curl -X DELETE https://httpbin.org/delete     # Delete

Headers

Headers are like the envelope of a letter: metadata about the request.

# Tell the server what format you want back
curl -H "Accept: application/json" https://httpbin.org/get

# Tell the server what format you are sending
curl -H "Content-Type: application/json" -d '{"key":"value"}' https://httpbin.org/post

# Authentication
curl -H "Authorization: Bearer token123" https://httpbin.org/bearer

# Custom headers
curl -H "X-API-Key: key123" -H "X-Request-ID: unique-id" https://httpbin.org/headers

Sending Data

# JSON data
curl -d '{"name":"Alice"}' -H "Content-Type: application/json" https://httpbin.org/post

# Form data
curl -d "name=Alice&age=30" https://httpbin.org/post

# File upload (multipart form)
curl -F "file=@document.pdf" https://httpbin.org/post

# Request body read from a file
curl -d @data.json https://httpbin.org/post

Try It Yourself

Exercise 1: Understand This curl Command

Identify each part:

curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer abc123" \
  -d '{"name":"John","email":"john@example.com"}'
Click for Answer - `-X POST` = use the POST method (creating something new) - URL = send to https://httpbin.org/post - First `-H` = tell the server we are sending JSON - Second `-H` = provide an authentication token - `-d` = the user data (name and email)

Exercise 2: Translate to CurlDotNet

Convert the command above to CurlDotNet C# code.

Click for Answer ```csharp var result = await Curl.ExecuteAsync(@" curl -X POST https://httpbin.org/post \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer abc123' \ -d '{""name"":""John"",""email"":""john@example.com""}' "); ``` Inside a C# verbatim string (`@"..."`), write each double quote as `""`.

Exercise 3: Real API Test

httpbin.org is a free service that echoes back whatever you send it:

using System;
using CurlDotNet;

var result = await Curl.ExecuteAsync(@"
    curl -X POST https://httpbin.org/post \
      -H 'Content-Type: application/json' \
      -d '{""message"":""Hello from CurlDotNet!""}'
");

Console.WriteLine($"Status: {result.StatusCode}");
Console.WriteLine($"Response: {result.Body}");

Common Mistakes

Mistake 1: Forgetting to Escape Quotes

// Wrong - the inner double quotes end the C# string early
var result = await Curl.ExecuteAsync("curl -d '{"name":"Alice"}' https://httpbin.org/post");

// Right - verbatim string with doubled quotes
var result = await Curl.ExecuteAsync(@"curl -d '{""name"":""Alice""}' https://httpbin.org/post");

Mistake 2: Launching the curl Binary Instead of CurlDotNet

// Wrong - starts an external curl process (if one is installed)
Process.Start("curl", "https://httpbin.org/get");

// Right - runs inside your .NET process
var result = await Curl.ExecuteAsync("curl https://httpbin.org/get");

Mistake 3: Forgetting async/await

// Wrong - missing await
var result = Curl.ExecuteAsync("curl https://httpbin.org/get");

// Right - with await
var result = await Curl.ExecuteAsync("curl https://httpbin.org/get");

curl Resources

Want to learn more about curl itself?

For CurlDotNet-specific help see the troubleshooting guide.

Key Takeaways

Questions You Might Have

Q: Do I need to install curl to use CurlDotNet? A: No. CurlDotNet is a pure .NET implementation.

Q: Can I use curl commands I find online directly? A: Yes, that is the point of the library. See the compatibility reference for the supported options.

Q: What if I don’t know curl syntax? A: CurlDotNet also has a fluent builder (CurlRequestBuilder) for building requests in code. Knowing curl is still useful because most API docs use it.

Q: Why not just use HttpClient? A: You can. CurlDotNet is handy when you already have curl commands from API documentation. See migrating from HttpClient.

Summary

curl is the common language developers use to talk to web services. CurlDotNet brings that language to C#: you paste a curl command into Curl.ExecuteAsync and get a typed CurlResult back, which removes the friction between reading API documentation and implementing it.

Next tutorial: Understanding Async/Await

Need help? Check the troubleshooting guide or ask in GitHub Discussions.