VastAI.NET
1.0.2
See the version list below for details.
dotnet add package VastAI.NET --version 1.0.2
NuGet\Install-Package VastAI.NET -Version 1.0.2
<PackageReference Include="VastAI.NET" Version="1.0.2" />
<PackageVersion Include="VastAI.NET" Version="1.0.2" />
<PackageReference Include="VastAI.NET" />
paket add VastAI.NET --version 1.0.2
#r "nuget: VastAI.NET, 1.0.2"
#:package VastAI.NET@1.0.2
#addin nuget:?package=VastAI.NET&version=1.0.2
#tool nuget:?package=VastAI.NET&version=1.0.2
VastAI.NET

VastAI.NET is a typed .NET client for the Vast.ai REST API.
Install
dotnet add package VastAI.NET
Configure
{
"VastAI": {
"ApiKey": "<vast-api-key>",
"ApiBaseUri": "https://console.vast.ai/"
}
}
The API key is required for live calls. Keep it in user secrets, environment variables, or host-specific secret storage.
Use With DI
using VastAI.NET;
builder.Services.AddVastAI(builder.Configuration);
var client = provider.GetRequiredService<IVastApiClient>();
var instances = await client.GetInstancesAsync();
Use With Runtime Values
Use this path when the API key is entered after startup, such as in a browser app or interactive CLI:
using VastAI.NET;
var client = VastApiClient.Create(apiKeyFromUserInput);
var instances = await client.GetInstancesAsync();
Hosts that already own an HttpClient can pass it:
var client = VastApiClient.Create(apiKeyFromUserInput, httpClient: httpClient);
API Usage
SearchOffersAsync
Use this to find rentable offers before creating an instance. Filters use Vast field names and comparison operators.
using VastAI.NET.Models;
var search = new VastSearchOffersRequest
{
Limit = 5,
Order = "dph_total"
};
search.Filters["rentable"] = new VastSearchFilter { EqualTo = true };
search.Filters["verified"] = new VastSearchFilter { EqualTo = true };
search.Filters["gpu_name"] = new VastSearchFilter { In = ["RTX_3060", "RTX_4090"] };
search.Filters["dph_total"] = new VastSearchFilter { LessThanOrEqualTo = 0.20 };
search.Filters["inet_up_cost"] = new VastSearchFilter { LessThanOrEqualTo = 1.0 / 1024.0 };
search.Filters["inet_down_cost"] = new VastSearchFilter { LessThanOrEqualTo = 1.0 / 1024.0 };
var offers = await client.SearchOffersAsync(search);
Order accepts compact Vast-style sort expressions: dph_total sorts ascending, dlperf_usd- sorts descending.
GetInstancesAsync
Use this for safety checks before renting and for account-level monitoring.
var instances = await client.GetInstancesAsync();
var active = instances.Where(instance => instance.IsActive).ToList();
VastInstance includes normalized status, label, GPU name, hourly price, estimated age, estimated cost, SSH target fields, public IP, exposed port mappings, and extra_env values when Vast returns them.
Use extra_env and exposed ports when reconnecting to software that was started by a Vast onstart command:
if (instance.TryGetExtraEnvironmentValue("VAST_LFS_TOKEN", out var workerToken) &&
instance.TryGetPublicUriForContainerPort(8088, out var workerUri))
{
Console.WriteLine(workerUri);
}
The full raw Vast instance object is also available for newly introduced Vast fields that do not yet have first-class properties:
if (instance.Raw.TryGetProperty("future_vast_field", out var value))
{
Console.WriteLine(value?.ToJsonString());
}
GetInstanceAsync
Use this after create, while waiting for boot, or when refreshing one known instance.
var instance = await client.GetInstanceAsync(instanceId);
if (instance.HasSshTarget)
{
Console.WriteLine($"{instance.SshUser}@{instance.SshHost}:{instance.SshPort}");
}
The parser handles Vast responses where instances is either an array or a single object.
CreateInstanceAsync
Use this only after selecting an offer and passing your own safety gates. This is a paid operation.
var create = new VastCreateInstanceRequest
{
DiskGb = 20,
Label = "lfs-smoke-test",
Image = "vastai/base-image:@vastai-automatic-tag",
RuntimeType = "ssh",
CancelUnavailable = true,
OnStart = "echo started"
};
create.Environment["-p 8080:8080"] = "1";
create.Environment["DATA_DIRECTORY"] = "/workspace/";
var result = await client.CreateInstanceAsync(offer.Id, create);
Console.WriteLine(result.InstanceId);
Vast REST requires Environment as a JSON object. Port mappings use keys such as -p 8080:8080 with value 1; environment variables use normal key/value pairs.
DestroyInstanceAsync
Use this to stop billing for an instance. Always call it from a finally block in tests or automation that rented an instance.
try
{
var result = await client.CreateInstanceAsync(offer.Id, create);
instanceId = result.InstanceId;
}
finally
{
if (!string.IsNullOrWhiteSpace(instanceId))
await client.DestroyInstanceAsync(instanceId);
}
The client uses bearer-token auth and the official Vast REST endpoints under https://console.vast.ai/.
Live Tests
Live tests are xUnit v3 explicit tests. They do not run during the normal suite.
dotnet user-secrets set "VastAI:ApiKey" "<vast-api-key>" --project .\tests\VastAI.NET.Tests\VastAI.NET.Tests.csproj
dotnet test .\tests\VastAI.NET.Tests\VastAI.NET.Tests.csproj --filter LiveVastApiTests -- xUnit.Explicit=on
CreateGetInstanceDestroyAsync_WithCheapLiveOffer_RentsAndDestroysInstance is paid. It rents one offer capped at $0.20/hr, destroys it in a finally block, and fails if active instances already exist.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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. |
-
net10.0
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Http.Resilience (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
-
net8.0
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Http.Resilience (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
-
net9.0
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Http.Resilience (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.