TofuPilot 1.6.3

dotnet add package TofuPilot --version 1.6.3
                    
NuGet\Install-Package TofuPilot -Version 1.6.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TofuPilot" Version="1.6.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TofuPilot" Version="1.6.3" />
                    
Directory.Packages.props
<PackageReference Include="TofuPilot" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TofuPilot --version 1.6.3
                    
#r "nuget: TofuPilot, 1.6.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TofuPilot@1.6.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TofuPilot&version=1.6.3
                    
Install as a Cake Addin
#tool nuget:?package=TofuPilot&version=1.6.3
                    
Install as a Cake Tool

TofuPilot C# SDK

NuGet License: MIT .NET

The unofficial open-source C# SDK for TofuPilot. Quickly and seamlessly integrate all your hardware test runs into one app with just a few lines of C#.

Table of Contents

Installation

Install via NuGet Package Manager:

dotnet add package TofuPilot

Or via Package Manager Console:

Install-Package TofuPilot

Quick Start

using TofuPilot;

// Create a client with your API key
using var client = new TofuPilotClient(apiKey: "your-api-key");

// List recent runs
var runs = await client.Runs.ListAsync(new ListRunsRequest { Limit = 10 });

// Create a new test run
var run = await client.Runs.CreateAsync(new CreateRunRequest
{
    ProcedureId = "your-procedure-id",
    Outcome = RunOutcome.PASS,
    SerialNumber = "SN-001",
    StartedAt = DateTimeOffset.UtcNow.AddMinutes(-5),
    EndedAt = DateTimeOffset.UtcNow
});

Console.WriteLine($"Created run: {run.Id}");

V2 API (Modern)

The V2 API provides a clean, resource-based interface for all TofuPilot operations.

Configuration

using TofuPilot;

// Basic usage
using var client = new TofuPilotClient(apiKey: "your-api-key");

// With custom base URL
using var client = new TofuPilotClient(
    apiKey: "your-api-key",
    baseUrl: "https://your-instance.tofupilot.com"
);

Creating a Run with Phases and Measurements

var request = new CreateRunRequest
{
    ProcedureId = "proc-123",
    Outcome = RunOutcome.PASS,
    SerialNumber = "UNIT-001",
    StartedAt = DateTimeOffset.UtcNow.AddMinutes(-10),
    EndedAt = DateTimeOffset.UtcNow,
    Phases = new List<CreateRunPhase>
    {
        new()
        {
            Name = "Voltage Test",
            Outcome = PhaseOutcome.PASS,
            StartTimeMillis = DateTimeOffset.UtcNow.AddMinutes(-10).ToUnixTimeMilliseconds(),
            EndTimeMillis = DateTimeOffset.UtcNow.AddMinutes(-5).ToUnixTimeMilliseconds(),
            Measurements = new List<CreateRunMeasurement>
            {
                new()
                {
                    Name = "Output Voltage",
                    Outcome = MeasurementOutcome.PASS,
                    MeasuredValue = 5.02,
                    Units = "V",
                    LowerLimit = 4.8,
                    UpperLimit = 5.2
                }
            }
        }
    }
};

var run = await client.Runs.CreateAsync(request);

Working with Units

// List units
var units = await client.Units.ListAsync(new ListUnitsRequest { Limit = 20 });

// Create a unit
var unit = await client.Units.CreateAsync(new CreateUnitRequest
{
    SerialNumber = "UNIT-001",
    PartNumber = "PART-A"
});

// Add a child unit (for assemblies)
await client.Units.AddChildAsync(parentUnitId, new AddChildRequest
{
    ChildId = childUnitId
});

Managing Procedures

// List procedures
var procedures = await client.Procedures.ListAsync(new ListProceduresRequest());

// Create a procedure
var procedure = await client.Procedures.CreateAsync(new CreateProcedureRequest
{
    Name = "Battery Test",
    Description = "Full battery charge/discharge cycle test"
});

// Create a version
var version = await client.Procedures.Versions.CreateAsync(
    procedureId: procedure.Id,
    new CreateVersionRequest { Name = "v1.0.0" }
);

Dependency Injection

The SDK supports ASP.NET Core dependency injection:

// In Program.cs or Startup.cs
services.AddTofuPilot(options =>
{
    options.ApiKey = configuration["TofuPilot:ApiKey"];
    options.BaseUrl = "https://www.tofupilot.com";
    options.Retry = new RetryOptions
    {
        MaxRetries = 3,
        InitialDelayMs = 1000,
        MaxDelayMs = 30000
    };
});

// In your service
public class TestRunService
{
    private readonly TofuPilotClient _client;

    public TestRunService(TofuPilotClient client)
    {
        _client = client;
    }

    public async Task<Run> CreateTestRunAsync(string serialNumber)
    {
        return await _client.Runs.CreateAsync(new CreateRunRequest
        {
            SerialNumber = serialNumber,
            // ...
        });
    }
}

Available Resources

Resource Methods
Runs ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync
Units ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync, AddChildAsync, RemoveChildAsync
Procedures ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync
Procedures.Versions ListAsync, CreateAsync, GetAsync, DeleteAsync
Parts ListAsync, CreateAsync, GetAsync, UpdateAsync
Parts.Revisions ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync
Batches ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync
Stations ListAsync, CreateAsync, GetAsync, UpdateAsync, RemoveAsync, LinkProcedureAsync, UnlinkProcedureAsync
Attachments InitializeAsync, DeleteAsync

Error Handling

The SDK throws specific exceptions for different error types:

using TofuPilot.Abstractions.Exceptions;

try
{
    var run = await client.Runs.GetAsync("invalid-id");
}
catch (NotFoundException ex)
{
    Console.WriteLine($"Run not found: {ex.Message}");
}
catch (UnauthorizedException ex)
{
    Console.WriteLine($"Invalid API key: {ex.Message}");
}
catch (BadRequestException ex)
{
    Console.WriteLine($"Invalid request: {ex.Message}");
    Console.WriteLine($"Response body: {ex.ResponseBody}");
}
catch (TofuPilotException ex)
{
    Console.WriteLine($"API error ({ex.StatusCode}): {ex.Message}");
}

Exception Types

Exception HTTP Status Description
BadRequestException 400 Invalid request parameters
UnauthorizedException 401 Invalid or missing API key
ForbiddenException 403 Access denied
NotFoundException 404 Resource not found
ConflictException 409 Resource conflict
UnprocessableEntityException 422 Validation error
RateLimitException 429 Rate limit exceeded
InternalServerErrorException 500 Server error
ServiceUnavailableException 503 Service unavailable

Contributing

Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.6.3 143 2/18/2026
1.6.2 252 2/13/2026
1.6.1 105 2/13/2026
1.6.0 83 2/11/2026
1.6.0-beta.7 40 2/11/2026
1.6.0-beta.3 40 2/11/2026
1.5.0 161 2/10/2026
1.5.0-beta.2 47 2/10/2026
1.4.1 94 2/10/2026
1.4.0 89 2/10/2026
1.4.0-beta.6 46 2/10/2026
1.3.0 91 2/10/2026
1.2.0 90 2/10/2026
1.1.0 95 2/10/2026