# Quickstart

This page takes you from a new account to your first result and your first machine. You need a terminal with `curl` and `python3`.

## 1. Sign in

Open [console.gpuforge.io](https://console.gpuforge.io) and sign in with Google or GitHub. Your account is created on first sign-in.

## 2. Add credit

GPU Forge is prepaid. In the console, open **Billing** and add credit by card. Payments are processed by Stripe; your card can be saved for later top-ups. A single top-up is between $5 and $5,000.

Nothing can start while your balance is $0.

## 3. Create an API key

In the console, open **API keys** and create a key. Give it a name that says where it will be used (for example `laptop` or `build-agent`).

The key starts with `gf_` and is **shown once**. Store it somewhere safe. Then put it in your shell:

```bash
export GF_KEY="gf_..."
export BASE="https://api.gpuforge.io"
```

Check that it works:

```bash
curl -s "$BASE/v1/billing" -H "Authorization: Bearer $GF_KEY"
```

```json
{
  "status": "ok",
  "balance_usd": 20.0,
  "cost_now_usd_hr": 0.0,
  "hours_left": null,
  "spend_usd": {"last_24h": 0.0, "last_7d": 0.0, "last_30d": 0.0},
  "machines": [],
  "daily_cap_usd": 100.0
}
```

(Some fields are left out here; see [Billing](billing.md).)

## 4. Run your first job

A job is one request to a ready program that returns one result. You pay only for the seconds it renders.

**Find a program.** The catalog lists the ready programs and the routes you can run as jobs:

```bash
curl -s "$BASE/v1/catalog" -H "Authorization: Bearer $GF_KEY"
```

```json
{
  "programs": [
    {
      "capability_id": "<program id>",
      "title": "...",
      "summary": "...",
      "avg_price_per_hour": 1.05,
      "job_routes": ["/v1/generate", "/v1/edit"],
      "added": null
    }
  ]
}
```

Copy the `capability_id` of an image program (FLUX 3 Klein or Krea 2). That is the **program id**.

```bash
export PROGRAM="<program id>"
```

**Get a quote.** You see the price before anything runs:

```bash
curl -s "$BASE/v1/jobs/quote?program=$PROGRAM&route=/v1/generate" \
  -H "Authorization: Bearer $GF_KEY"
```

```json
{"program": "<program id>", "route": "/v1/generate", "quote_usd": 0.002}
```

**Send the job.** `input` is the JSON body the program's route takes (see [Ready programs](programs.md)). `max_price_usd` is optional: if the quote is above it, the job is refused and nothing runs.

```bash
curl -s "$BASE/v1/jobs" \
  -H "Authorization: Bearer $GF_KEY" -H "Content-Type: application/json" \
  -d '{
    "program": "'"$PROGRAM"'",
    "route": "/v1/generate",
    "input": {
      "prompt": "Full-color photograph of a mountain lake at sunrise, mist over the water, a pine forest on the far shore, soft golden light.",
      "width": 1216, "height": 832, "seed": 7
    },
    "max_price_usd": 0.05
  }'
```

```json
{
  "job_id": "job_3f9a1c2b7d4e",
  "status": "queued",
  "quote_usd": 0.002,
  "next": "GET /v1/jobs/job_3f9a1c2b7d4e?wait=60 answers when it is done"
}
```

**Wait for the result and save the image.** `wait` holds the request open (up to 120 seconds) and answers as soon as the job is done:

```bash
curl -s "$BASE/v1/jobs/job_3f9a1c2b7d4e?wait=60" -H "Authorization: Bearer $GF_KEY" \
  | python3 -c "import sys,json,base64; j=json.load(sys.stdin); print(j['status'], j['price_usd']); \
open('lake.jpg','wb').write(base64.b64decode(j['result']['image'])) if j['status']=='done' else print(j)"
```

If the status is still `queued` or `running`, call the same URL again. The first job after a quiet period can wait a few minutes while a machine wakes or starts; that wait is not billed. A job that fails is not charged.

Results are kept for 24 hours after the job finishes, then deleted. Save what you want to keep.

## 5. Rent your first machine

A machine runs one program. You can run one of our ready programs on a machine of your own, or your own software.

### Option A: a ready program on your own machine

1. **Add the program to your account.** This makes your own copy of it and a **program key** for its machine.

   ```bash
   curl -s -X POST "$BASE/v1/catalog/$PROGRAM/add" \
     -H "Authorization: Bearer $GF_KEY" -H "Content-Type: application/json" -d '{}'
   ```

   ```json
   {
     "capability_id": "cap_ab12cd34",
     "name": "...",
     "version": "...",
     "gf_api_key": "gfv_...",
     "note": "Your machine key is shown once — keep it. ...",
     "next": "POST /v1/capabilities/cap_ab12cd34/deploy, then GET /v1/fleet/<pod_id> ..."
   }
   ```

   The `gf_api_key` is shown once. It opens the program on your machine; it is not a GPU Forge API key. From now on use **your copy's** `capability_id`.

2. **Start a machine.** GPU Forge wakes a parked machine of this program if one is free (seconds), otherwise rents the cheapest machine that fits under the program's price limit (minutes).

   ```bash
   curl -s -X POST "$BASE/v1/capabilities/cap_ab12cd34/deploy" -H "Authorization: Bearer $GF_KEY"
   ```

   The answer has a `pod_id` and the hourly `price_usd_hr`. **The machine bills from now on.**

3. **Wait until it is ready.** Poll every 10 seconds until `capability_state` is `ready`. The `status` field is one plain sentence about what the machine is doing.

   ```bash
   curl -s "$BASE/v1/fleet/<pod_id>" -H "Authorization: Bearer $GF_KEY" \
     | python3 -c "import sys,json; p=json.load(sys.stdin); print(p['capability_state'], '|', p['status'], '|', p['capability_url'])"
   ```

   A machine that already holds the program is usually ready in 1–3 minutes; a fresh one can take up to 15–20 minutes.

4. **Use the program.** Each program has its own API on the machine, with a guide at `/v1`:

   ```bash
   curl -s "<capability_url>/v1" -H "Authorization: Bearer gfv_..."
   ```

5. **Stop it when you are done.** `release` parks the machine if your program keeps parked machines, otherwise ends it. A machine with no work also parks or stops by itself after the program's idle limit (10 minutes by default), but it bills until then.

   ```bash
   curl -s -X POST "$BASE/v1/fleet/<pod_id>/release" -H "Authorization: Bearer $GF_KEY" \
     -H "Content-Type: application/json" -d '{}'
   ```

Nothing is kept on a ready program's machine between starts. Download every result as soon as it is made.

### Option B: your own software

1. **Find your account id.** Capabilities are created for an account:

   ```bash
   curl -s "$BASE/v1/cli/whoami" -H "Authorization: Bearer $GF_KEY"
   ```

   Note the `user_id` (`usr_...`).

2. **Describe your software once** as a capability. This minimal example serves a directory listing on port 8000 and lets you log in over SSH with your own public key:

   ```bash
   curl -s "$BASE/v1/capabilities" \
     -H "Authorization: Bearer $GF_KEY" -H "Content-Type: application/json" \
     -d '{
       "name": "hello-gpu",
       "user_id": "usr_...",
       "spec": {
         "min_vram_gb": 24,
         "disk_gb": 50,
         "min_gpu_family": "ada_lovelace",
         "start": "python3 -m http.server 8000",
         "port": 8000,
         "ready_check": {"path": "/"},
         "max_price_per_hour": 1.0,
         "idle_ttl_seconds": 1800,
         "ssh_public_keys": ["ssh-ed25519 AAAA... you@laptop"]
       }
     }'
   ```

   The answer has a `capability_id`. Nothing is rented yet. See [Capabilities](capabilities.md) for every field.

3. **Rent a machine** for it. GPU Forge searches every provider and rents the cheapest machine that fits under `max_price_per_hour`:

   ```bash
   curl -s -X POST "$BASE/v1/capabilities/<capability_id>/deploy" -H "Authorization: Bearer $GF_KEY"
   ```

4. **Wait for `capability_state: ready`** as in Option A, then open `capability_url`, or get the SSH command:

   ```bash
   curl -s "$BASE/v1/fleet/<pod_id>/ssh" -H "Authorization: Bearer $GF_KEY"
   # "state": "configured", "command": "ssh -p 41022 root@203.0.113.10"
   ```

5. **Destroy it** when you no longer need it. This ends the rental and deletes its disk:

   ```bash
   curl -s -X POST "$BASE/v1/fleet/<pod_id>/destroy" -H "Authorization: Bearer $GF_KEY" \
     -H "Content-Type: application/json" -d '{}'
   ```

## Next steps

- [How GPU Forge behaves](principles.md): what you pay for and what happens when.
- [Jobs](jobs.md) and [Ready programs](programs.md): every field of every program.
- [Command-line tool](cli.md): the same flows from your terminal.
