SoftwareTestPilot
API TestingPublished: 9 min read

RestSharp C# API Automation: Complete 2026 Guide

Complete RestSharp C# API automation guide for 2026. Setup, CRUD operations, authentication, schema validation, mocking, and CI/CD integration.

Avinash Kamble
Avinash Kamble
Founder & QA Engineer at SoftwareTestPilot
Reviewed by Priyanka G.
Share:XLinkedInWhatsApp
RestSharp C# API automation — flat editorial illustration of a code window sending HTTP requests through a CI/CD pipeline into a server stack.
RestSharp C# API automation — flat editorial illustration of a code window sending HTTP requests through a CI/CD pipeline into a server stack.
In this article
  1. What is RestSharp?
  2. Step 1 — Install RestSharp
  3. Step 2 — Your First GET Request
  4. Step 3 — Deserialize JSON
  5. Step 4 — POST Requests
  6. Step 5 — PUT and DELETE
  7. Step 6 — Authentication
  8. Step 7 — Query Parameters
  9. Step 8 — Schema Validation
  10. Step 9 — Reusable Client Setup
  11. Step 10 — Mocking with WireMock
  12. Step 11 — CI/CD Integration
  13. Best Practices
  14. Common RestSharp Mistakes and Fixes
  15. Continue your API automation journey
  16. Frequently asked questions

Last updated: June 27, 2026 · 9 min read

This guide covers everything you need to automate API testing with RestSharp in C#: setup, CRUD operations, authentication, schema validation, mocking, and CI/CD integration. Pair it with our API Testing Tutorial, RestSharp C# fundamentals, and REST Assured Java guide.

What is RestSharp?

RestSharp is a simple REST and HTTP API client for .NET. It wraps HttpClient with a fluent API that handles JSON serialization, authentication, and error handling out of the box. Docs: restsharp.dev.

Step 1 — Install RestSharp

dotnet new nunit -n RestSharpDemo
cd RestSharpDemo
dotnet add package RestSharp
dotnet add package Newtonsoft.Json

Step 2 — Your First GET Request

using RestSharp;
using NUnit.Framework;

public class UserApiTests
{
    private RestClient _client;

    [SetUp]
    public void SetUp()
    {
        _client = new RestClient("https://jsonplaceholder.typicode.com");
    }

    [Test]
    public void GetUserById()
    {
        var request = new RestRequest("/users/{id}", Method.Get);
        request.AddUrlSegment("id", "1");

        var response = _client.Execute(request);

        Assert.That(response.StatusCode, Is.EqualTo(System.Net.HttpStatusCode.OK));
        Assert.That(response.Content, Does.Contain("Leanne Graham"));
    }
}

Step 3 — Deserialize JSON

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

[Test]
public void GetUserByIdDeserialized()
{
    var request = new RestRequest("/users/{id}", Method.Get);
    request.AddUrlSegment("id", "1");

    var response = _client.Execute<User>(request);

    Assert.That(response.StatusCode, Is.EqualTo(System.Net.HttpStatusCode.OK));
    Assert.That(response.Data.Name, Is.EqualTo("Leanne Graham"));
    Assert.That(response.Data.Email, Does.Contain("@"));
}

Step 4 — POST Requests

[Test]
public void CreateUser()
{
    var request = new RestRequest("/users", Method.Post)
        .AddJsonBody(new
        {
            name = "Alice Johnson",
            email = "alice@example.com",
            role = "admin"
        });

    var response = _client.Execute(request);

    Assert.That((int)response.StatusCode, Is.EqualTo(201));
    var json = JObject.Parse(response.Content);
    Assert.That(json["email"]?.ToString(), Is.EqualTo("alice@example.com"));
}

Step 5 — PUT and DELETE

[Test]
public void UpdateUser()
{
    var request = new RestRequest("/users/{id}", Method.Put)
        .AddUrlSegment("id", "1")
        .AddJsonBody(new { name = "Alice Updated" });

    var response = _client.Execute(request);

    Assert.That((int)response.StatusCode, Is.EqualTo(200));
}

[Test]
public void DeleteUser()
{
    var request = new RestRequest("/users/{id}", Method.Delete)
        .AddUrlSegment("id", "1");

    var response = _client.Execute(request);

    Assert.That((int)response.StatusCode, Is.EqualTo(200).Or.EqualTo(204));
}

Step 6 — Authentication

Bearer Token

[Test]
public void AuthenticatedRequest()
{
    var token = GetAuthToken();
    _client.AddDefaultHeader("Authorization", $"Bearer {token}");

    var request = new RestRequest("/admin/users", Method.Get);
    var response = _client.Execute(request);

    Assert.That((int)response.StatusCode, Is.EqualTo(200));
}

private string GetAuthToken()
{
    var authRequest = new RestRequest("/auth/login", Method.Post)
        .AddJsonBody(new { email = "admin@example.com", password = "Sup3rSecret!" });

    return _client.Execute<TokenResponse>(authRequest).Data.Token;
}

public class TokenResponse
{
    public string Token { get; set; }
}

Basic Auth

_client.Authenticator = new HttpBasicAuthenticator("admin", "Sup3rSecret!");

Step 7 — Query Parameters

var request = new RestRequest("/users", Method.Get)
    .AddQueryParameter("page", "1")
    .AddQueryParameter("limit", "10");

Step 8 — Schema Validation

Use Newtonsoft.Json.Schema:

dotnet add package Newtonsoft.Json.Schema
[Test]
public void ValidateResponseSchema()
{
    var schemaJson = File.ReadAllText("schemas/user.json");
    var schema = JSchema.Parse(schemaJson);

    var request = new RestRequest("/users/{id}", Method.Get)
        .AddUrlSegment("id", "1");

    var response = _client.Execute(request);
    var json = JObject.Parse(response.Content);

    var isValid = json.IsValid(schema, out var errors);
    Assert.That(isValid, Is.True, $"Schema validation failed: {string.Join(", ", errors)}");
}

Step 9 — Reusable Client Setup

public class ApiClient
{
    public RestClient Client { get; }

    public ApiClient(string baseUrl)
    {
        Client = new RestClient(baseUrl);
    }

    public async Task<RestResponse<T>> GetAsync<T>(string resource)
    {
        return await Client.ExecuteAsync<T>(new RestRequest(resource, Method.Get));
    }

    public async Task<RestResponse<T>> PostAsync<T>(string resource, object body)
    {
        var request = new RestRequest(resource, Method.Post).AddJsonBody(body);
        return await Client.ExecuteAsync<T>(request);
    }

    public async Task<RestResponse> DeleteAsync(string resource)
    {
        return await Client.ExecuteAsync(new RestRequest(resource, Method.Delete));
    }
}

Step 10 — Mocking with WireMock

dotnet add package WireMock.Net
public class MockedApiTests
{
    private WireMockServer _server;
    private RestClient _client;

    [SetUp]
    public void SetUp()
    {
        _server = WireMockServer.Start(8080);
        _server.Given(Request.Create().WithPath("/api/users/1").UsingGet())
              .RespondWith(Response.Create()
                  .WithStatusCode(200)
                  .WithBody("{ \"id\": 1, \"name\": \"Mock User\" }"));

        _client = new RestClient("http://localhost:8080");
    }

    [TearDown]
    public void TearDown() { _server.Stop(); }

    [Test]
    public void TestAgainstMock()
    {
        var request = new RestRequest("/api/users/1", Method.Get);
        var response = _client.Execute(request);

        Assert.That((int)response.StatusCode, Is.EqualTo(200));
    }
}

See more options in our free API mocking tools roundup.

Step 11 — CI/CD Integration

GitHub Actions

name: RestSharp Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
        with: { dotnet-version: '8.0.x' }
      - run: dotnet restore
      - run: dotnet test --logger "trx;LogFileName=results.trx"
      - uses: actions/upload-artifact@v4
        if: ${{ !cancelled() }}
        with:
          name: test-results
          path: TestResults/

For deeper pipeline patterns, see our CI/CD pipeline testing tutorial and GitHub Actions for automation testing guide.

Best Practices

Do

  • Use async/await for scalability
  • Validate response schemas on every test
  • Use mocks for external dependencies
  • Store credentials in secrets, not source
  • Track metrics (response time, error rate)

Don't

  • Don't hardcode URLs or credentials
  • Don't chain tests that depend on each other
  • Don't ignore HTTP error codes
  • Don't skip schema validation

Common RestSharp Mistakes and Fixes

Mistake 1 — Not using async

// BAD
var response = client.Execute(request);

// GOOD
var response = await client.ExecuteAsync(request);

Mistake 2 — Hardcoded URLs

// BAD
var client = new RestClient("https://api.example.com");

// GOOD
var baseUrl = Environment.GetEnvironmentVariable("API_BASE_URL") ?? "https://staging.example.com";
var client = new RestClient(baseUrl);

Mistake 3 — Ignoring HTTP status codes

if (!response.IsSuccessful) {
    Assert.Fail($"Request failed: {response.StatusCode} - {response.ErrorMessage}");
}

Mistake 4 — Not validating response schema

var schema = JSchema.Parse(File.ReadAllText("schemas/user.json"));
var body = JObject.Parse(response.Content);
Assert.That(body.IsValid(schema), Is.True);

Mistake 5 — Sharing state across tests

Use fresh client instances per test. Don't share state via static fields.

Mistake 6 — Not handling rate limits

public async Task<RestResponse> ExecuteWithRetry(RestRequest request)
{
    for (int i = 0; i < 3; i++)
    {
        var response = await client.ExecuteAsync(request);
        if (response.StatusCode != HttpStatusCode.TooManyRequests)
            return response;
        await Task.Delay(1000 * (i + 1));
    }
    throw new Exception("Rate limit exceeded");
}

Mistake 7 — Not logging failures

if (!response.IsSuccessful) {
    Log.Error($"Request: {request.Method} {request.Resource}");
    Log.Error($"Response: {response.StatusCode} {response.Content}");
}

Frequently asked questions

Is RestSharp still relevant in 2026?

Yes — RestSharp v110+ is actively maintained. It's the most popular HTTP client for .NET API testing.

RestSharp vs HttpClient — which should I use?

Use RestSharp for API testing (less boilerplate). Use HttpClient for production code (more control).

Can RestSharp deserialize JSON automatically?

Yes — pass a type to ExecuteAsync<T>() and RestSharp handles JSON deserialization.

How do I mock APIs in RestSharp tests?

Use WireMock.Net for full mocking, or stub responses with a local test server.

How do I handle rate limiting in tests?

Implement retry logic with exponential backoff, or use a sandbox API that doesn't rate-limit.

Is RestSharp free?

Yes — RestSharp is free and open source under the Apache 2.0 license.

Keep going

Practice these questions

Rehearse REST, Postman, REST Assured and contract-testing questions with worked examples.

Found this useful?
Share:XLinkedInWhatsApp

Was this article helpful?

Keep building your QA edge

Continue reading

Join the QA Community

Connect with fellow testers, share job leads, and get career advice.

Premium QA Resources

Stop Reinventing the Wheel. Upgrade Your QA Arsenal.

Take your testing skills from beginner to Lead Engineer. Supercharge your daily workflow with our premium digital resources.

  • ⚡ Ready-to-use testing strategy templates
  • 🔥 Advanced API & UI automation guides
  • ⏱️ Save 10+ hours a week on test planning
4.9/5 rating
Explore All Products

⭐⭐⭐⭐⭐ Trusted by 1,000+ Software Test Pilots • Instant Access