# SDKs

Quivvo has SDKs for TypeScript and Python. Both wrap the [REST API](https://tryquivvo.com/docs/api), have no dependencies, and follow the API's rules for you: an `Idempotency-Key` on every lifecycle call, retries only when they're safe, and the API's error object as an exception. 

## TypeScript

```bash
npm install quivvo-sdk
```

```ts
import { Quivvo } from "quivvo-sdk";

const q = new Quivvo(); // reads QUIVVO_API_KEY

const m = await q.machines.create({ name: "dev" });
const r = await m.exec("uname -a");
console.log(r.exit_code, r.stdout);

for await (const ev of q.machines.execStream("dev", "npm test")) {
  if (ev.event === "stdout") process.stdout.write(ev.data);
}

await q.machines.suspend("dev");
```

It uses only `fetch`, so it runs on Node.js 18 or later, Bun, Deno and edge runtimes. Every method takes `{ signal, timeoutMs, maxRetries }` last.

## Python

```bash
pip install quivvo
```

```python
from quivvo import Quivvo

q = Quivvo()  # reads QUIVVO_API_KEY

m = q.machines.create(name="dev")
r = m.exec("uname -a")
print(r["exit_code"], r["stdout"])

for ev in q.machines.exec_stream("dev", "npm test"):
    if ev["event"] == "stdout":
        print(ev["data"], end="")

q.machines.suspend("dev")
```

It needs Python 3.9 or later and uses only the standard library.

## What do they cover?

Everything a key can do over the API: machines and their lifecycle, commands (waiting for the result or streaming it), background jobs and their logs, files, ports, snapshots, forks and restores, keys, webhooks, usage, `whoami` and the catalog. Device sign-in isn't in them: get a key with `quivvo login` or from [API keys](https://tryquivvo.com/app/keys), and pass it as `apiKey` / `api_key` or set `QUIVVO_API_KEY`.

## How do errors work?

An error the API sends raises `QuivvoError`, with the same fields as the [error object](https://tryquivvo.com/docs/errors): `code`, `message`, `retryable`, the seconds to wait, `docs_url`, `request_id` and `owner_action`. Branch on `code`. A request that got no answer raises `QuivvoNetworkError`, which says whether the request may have reached the server, so you know whether repeating it is safe.

A command that exits non-zero isn't an error: read its exit code. A command is only sent again when the API says it didn't run.
