# For AI agents

This page is for an AI agent (or its developer) that has been pointed at Green Compute and needs to use it without a human clicking through a dashboard.

## What Green Compute is

GPU compute on Bittensor subnet 110, run on renewable and biogas power. Two products, both over one HTTP API:

1. **GPU rental:** an SSH-accessible container on an RTX 4090 or 5090, billed per minute. See [Quickstart](https://www.green-compute.com/docs/quickstart.md).
2. **Inference:** OpenAI-compatible chat completions. See [Inference](https://www.green-compute.com/docs/inference.md).

## Machine-readable entry points

| What | URL | Auth |
|---|---|---|
| This documentation, as one file | `https://www.green-compute.com/llms-full.txt` | none |
| Documentation index | `https://www.green-compute.com/llms.txt` | none |
| Any docs page as Markdown | append `.md`, e.g. `https://www.green-compute.com/docs/quickstart.md` | none |
| OpenAPI spec | `https://api.green-compute.com/openapi.json` | none |
| API index | `https://api.green-compute.com/` | none |
| Prices | `https://api.green-compute.com/platform/pricing` | none |
| Rentable GPU ids | `https://api.green-compute.com/platform/nodes/supported` | none |
| Free GPUs right now | `https://control.green-compute.com/platform/v1/gpu-pool` | none |

## What needs a human, once

Creating the account, adding credit and creating the API key happen in the browser. After that, everything is API. If you have no key, ask your user for one. Point them at [green-compute.com/settings](https://www.green-compute.com/settings) and [green-compute.com/billing](https://www.green-compute.com/billing).

## Rules of thumb

- **Use your own SSH public key** in `metadata.ssh_public_keys`. Then you never need to fetch, store or log a private key.
- **Budget from the API, not from prose.** `hourly_rate_cents` on a new deployment is the most it can cost per GPU-hour; `/platform/pricing` is what billing charges.
- **Always clean up.** `DELETE /platform/deployments/{id}` stops billing. Wrap your work so this runs even on failure.
- **Poll, don't sleep blindly.** `GET /platform/deployments/{id}` every 5–10 s until `state` is `ready`; stop on `failed` and read `last_error`.
- **Errors are actionable.** A `400` for an unavailable GPU lists the GPUs that are available; a `402` gives the exact amount to top up. See [Errors](https://www.green-compute.com/docs/errors.md).
- **For an RTX 5090, use a CUDA 12.8+ image.** `pytorch/pytorch:2.7.0-cuda12.8-cudnn9-runtime` works on both cards.
- **One-off commands work over SSH.** `ssh root@host -p port 'python train.py'` uses the image's `PATH`, so conda/PyTorch images behave as documented.

## Minimal loop (Python, standard library only)

```python
import json, os, time, urllib.request

API = "https://api.green-compute.com"
KEY = os.environ["GC_KEY"]

def call(method, path, body=None):
    req = urllib.request.Request(
        API + path, method=method,
        data=json.dumps(body).encode() if body is not None else None,
        headers={"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req) as r:
        return json.loads(r.read() or b"null")

pubkey = open(os.path.expanduser("~/.ssh/id_ed25519.pub")).read().strip()
wl = call("POST", "/platform/workloads", {
    "name": "agent-job", "kind": "pod",
    "image": "pytorch/pytorch:2.7.0-cuda12.8-cudnn9-runtime",
    "requirements": {"gpu_count": 1, "supported_gpu_models": ["rtx4090"],
                     "min_vram_gb_per_gpu": 24, "cpu_cores": 8, "memory_gb": 32},
    "metadata": {"ssh_public_keys": [pubkey]},
})
dep = call("POST", "/platform/deployments", {"workload_id": wl["workload_id"]})
try:
    while (d := call("GET", f"/platform/deployments/{dep['deployment_id']}"))["state"] not in ("ready", "failed"):
        time.sleep(10)
    if d["state"] == "failed":
        raise RuntimeError(d.get("last_error"))
    ssh = call("GET", f"/platform/deployments/{dep['deployment_id']}/ssh")
    print("connect with:", ssh["ssh_command"])
    # ... do the work over SSH ...
finally:
    call("DELETE", f"/platform/deployments/{dep['deployment_id']}")
```
