> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aireserve.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDKs

> The GPU surface from Python, TypeScript, Go, Java and Rust: quote, launch, wait, connect, store, cluster — the same provider-hidden contract as the CLI and the REST API.

Every AI Reserve SDK exposes GPU infrastructure as `client.gpu`, a typed
mirror of the `/v1/gpu` REST API. The request names an accelerator, a count,
a region and a price ceiling; AI Reserve places it on whichever backing
provider has stock, and the SDK never receives, needs or exposes a provider,
data center or tenancy. Whichever provider served a resource, the same calls
work; the `capabilities` flags on quotes and resources are the only
provider-derived facts, and the SDKs consult them rather than assume.

| Language | Package | Namespace | Minimum version |
| - | - | - | - |
| Python | `pip install aireserve` | `client.gpu` | 0.10.0 |
| TypeScript | `npm install @aireserve/sdk` | `client.gpu` | 0.8.0 |
| Go | `go get github.com/Audacity-Investments/aireserve-sdk-go` | `client.Gpu` | 0.8.0 |
| Java | `com.aireserve:aireserve-sdk` | `client.gpu()` | 0.8.0 |
| Rust | `aireserve` crate | `client.gpu()` | 0.8.0 |

Every language carries the full surface: `offers`, `instances` (quote, launch,
list, get, connections, logs, stop, start, terminate, recovery), `clusters`
(quote, launch, list, get, connections, logs per node, terminate, recovery),
`volumes` (create, list, get, grow, delete), `sshKeys`, `registries`,
`templates`, `operations` and `usage`. Authentication is the SDK's usual
credential chain (`AIRESERVE_API_KEY`, or a management token from
`aireserve login`); the key needs **Compute** permission.

## Quote, launch, connect, terminate

```python Python theme={"dark"}
from aireserve import Aireserve

client = Aireserve()  # AIRESERVE_API_KEY
quote = client.gpu.instances.quote(accelerator="H100_80GB", region="united_states", storage={"persistentGb": 500})
print(quote.price.total_running_usd_per_hour, "per hour;", quote.price.storage_only_usd_per_hour, "after stop")

op = client.gpu.instances.launch(quote_id=quote.quote_id, ssh_public_key=open("/home/me/.ssh/id_ed25519.pub").read())
instance = op.wait(timeout=600)
print(client.gpu.instances.connections(instance.id).ssh.command)

for event in client.gpu.instances.logs(instance.id, tail=100, source="container"):
    print(event.timestamp, event.line)

client.gpu.instances.terminate(instance.id).wait()
```

```ts TypeScript theme={"dark"}
import { AireserveRuntimeClient } from "@aireserve/sdk";

const client = new AireserveRuntimeClient(); // AIRESERVE_API_KEY
const quote = await client.gpu.instances.quote({ accelerator: "H100_80GB", region: "united_states", storage: { persistentGb: 500 } });

const op = await client.gpu.instances.launch({ quoteId: quote.quoteId, sshPublicKey });
const instance = await op.wait({ timeoutMs: 600_000 });
const { ssh } = await client.gpu.instances.connections(instance.id);

for await (const event of client.gpu.instances.logs(instance.id, { tail: 100, source: "container" })) console.log(event.line);

await (await client.gpu.instances.terminate(instance.id)).wait();
```

```go Go theme={"dark"}
client := aireserve.NewClient()
quote, err := client.Gpu.Instances.Quote(ctx, aireserve.InstanceRequest{Accelerator: "H100_80GB", Region: "united_states"})
op, err := client.Gpu.Instances.Launch(ctx, aireserve.InstanceLaunch{QuoteID: quote.QuoteID, SSHPublicKey: key})
instance, err := op.Wait(ctx, nil)
conn, err := client.Gpu.Instances.Connections(ctx, instance.ID)
_, err = client.Gpu.Instances.Terminate(ctx, instance.ID, nil)
```

```java Java theme={"dark"}
var client = AireserveRuntimeClient.builder().build();
var quote = client.gpu().instances().quote(InstanceRequest.builder().accelerator("H100_80GB").region("united_states").build());
var instance = client.gpu().instances().launch(InstanceLaunch.builder().quoteId(quote.quoteId()).sshPublicKey(key).build()).waitFor();
var ssh = client.gpu().instances().connections(instance.id()).ssh();
client.gpu().instances().terminate(instance.id()).waitFor();
```

```rust Rust theme={"dark"}
let client = Client::from_env()?;
let quote = client.gpu().instances().quote(&InstanceRequest { accelerator: "H100_80GB".into(), region: Some("united_states".into()), ..Default::default() }).await?;
let instance = client.gpu().instances().launch(&InstanceLaunch { quote_id: Some(quote.quote_id.clone()), ssh_public_key: Some(key), ..Default::default() }).await?.wait(None).await?;
let conn = client.gpu().instances().connections(&instance.id).await?;
client.gpu().instances().terminate(&instance.id, None).await?.wait(None).await?;
```

## What every SDK guarantees

* **Mutations are idempotent.** Every launch, stop, start, terminate, create,
  grow, delete, rotate and recovery call sends an `Idempotency-Key`
  (`sdk-<resource>-<action>-<uuid>` unless you pass one) and returns a typed
  operation handle. `wait()` polls `GET /v1/gpu/operations/{id}` with
  backoff (1 s → 5 s), then fetches the resource; a failed operation raises
  `OperationFailedError` carrying the structured `failure` (`code`, `actor`,
  `message`, `next`); running out of time raises `OperationTimeoutError`.
* **Refusals are typed.** `409 no_capacity` is `NoCapacityError` with
  `reason` (`no_stock`, `price_ceiling`, `volume_location`,
  `no_persistent_storage`), `cheapestEligibleUsdPerHour` and `alternatives`;
  `quote_expired` and `price_changed` are distinct exceptions;
  `insufficient_funds` maps to the quota exception.
* **Money is a string.** Every price is a six-decimal USD string, never a
  float.
* **No provider surfaces.** SDK types carry `region`, never a data-center id;
  `accelerator` ids are the public ones `offers.list()` returns; the legacy
  provider-shaped `/v1/gpu/pods`, `/v1/gpu/catalog` and `/v1/gpu/quotes` routes
  are not exposed.
* **Clusters take no registry credential**, exactly like the API; a private
  image needs a single instance.
* **Logs** are an iterator of `{ timestamp, source, line, eventId }` with
  `tail`, `source`, `since` (and `node` for clusters); the SDK reconnects
  across relay windows with `Last-Event-ID`.

## Conformance

The SDKs are specified once, in the SDK repository's `SPEC.md` (section 10),
and tested against one shared fixture corpus recorded from AI Reserve's
two-provider end-to-end harness, so Python, TypeScript, Go, Java and Rust
replay byte-identical server behavior for every scenario above, including a
resource placed on a marketplace provider and a cluster request no provider
can place.

Related: the [CLI](https://docs.aireserve.com/connect/cli.md) is the same contract from a shell; the
[MCP server](https://docs.aireserve.com/connect/mcp-tools.md) gives a coding agent the same surface as
tools.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.