VastAI.NET is a typed .NET client for the Vast.ai REST API.
dotnet add package VastAI.NET{
"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.
using VastAI.NET;
builder.Services.AddVastAI(builder.Configuration);
var client = provider.GetRequiredService<IVastApiClient>();
var instances = await client.GetInstancesAsync();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);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.
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());
}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.
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.
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 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=onCreateGetInstanceDestroyAsync_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.