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

# Quickstart

> Get your first GPU offer in under 5 minutes

## Prerequisites

* An API token (contact our [sales team](mailto:michael@compute-index.com))
* `curl`, Python with `requests`, or Node.js with `node-fetch`

## Authentication

All API requests require a Bearer token in the `Authorization` header.

Your token is non-transferable — all charges and resources are associated to your account through your token.

| Status             | Meaning                                                            |
| ------------------ | ------------------------------------------------------------------ |
| `401 Unauthorized` | Missing, invalid, or expired token                                 |
| `403 Forbidden`    | Token is valid but you don't have access to the requested resource |

## Step 1: Check available GPUs

<CodeGroup>
  ```bash curl theme={null}
  curl https://supply-api.compute-desk.com/available_gpus \
    -H "Authorization: Bearer $TOKEN"
  ```

  ```python Python theme={null}
  import requests

  headers = {"Authorization": "Bearer YOUR_TOKEN"}
  resp = requests.get("https://supply-api.compute-desk.com/available_gpus", headers=headers)
  gpu_types = resp.json().get("gpu_types", [])
  print(f"Available: {gpu_types}")
  ```

  ```typescript TypeScript theme={null}
  const headers = { Authorization: "Bearer YOUR_TOKEN" };
  const resp = await fetch("https://supply-api.compute-desk.com/available_gpus", { headers });
  const { gpu_types } = await resp.json() as any;
  console.log("Available:", gpu_types);
  ```
</CodeGroup>

This returns GPU family names (like `H100`) and their canonical variants (like `nvidia-h100-sxm5-80gb`). You can use either format when requesting offers.

## Step 2: Get offers

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://supply-api.compute-desk.com/get_offers \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/yaml" \
    -d '
  compute:
    gpu_type: H100
    gpu_count: 1
    max_price_per_gpu_hour: 5
    contract_type: ondemand
  '
  ```

  ```python Python theme={null}
  yaml_spec = """
  compute:
    gpu_type: H100
    gpu_count: 1
    max_price_per_gpu_hour: 5
    contract_type: ondemand
  """

  resp = requests.post(
      "https://supply-api.compute-desk.com/get_offers",
      data=yaml_spec,
      headers={**headers, "Content-Type": "application/yaml"},
  )
  offers = resp.json()["offers"]
  cheapest = min(offers, key=lambda o: o["gpu_price_per_hour"])
  print(f"Cheapest: {cheapest['offer_id']} at ${cheapest['gpu_price_per_hour']:.4f}/GPU/hr")
  ```

  ```typescript TypeScript theme={null}
  const yamlSpec = `
  compute:
    gpu_type: H100
    gpu_count: 1
    max_price_per_gpu_hour: 5
    contract_type: ondemand
  `;

  const offersResp = await fetch("https://supply-api.compute-desk.com/get_offers", {
    method: "POST",
    headers: { ...headers, "Content-Type": "application/yaml" },
    body: yamlSpec,
  });
  const { offers } = await offersResp.json() as any;
  const cheapest = offers.reduce((a: any, b: any) =>
    a.gpu_price_per_hour < b.gpu_price_per_hour ? a : b
  );
  console.log(`Cheapest: ${cheapest.offer_id} at $${cheapest.gpu_price_per_hour.toFixed(4)}/GPU/hr`);
  ```
</CodeGroup>

The response includes offers from all vendors, sorted by price. Each offer has an `offer_id` and expires after 30 minutes.

## Step 3: Procure an offer

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://supply-api.compute-desk.com/procure_offer \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "offer_id": "YOUR_OFFER_ID",
      "ssh_public_key": "ssh-ed25519 AAAA... your-key"
    }'
  ```

  ```python Python theme={null}
  result = requests.post(
      "https://supply-api.compute-desk.com/procure_offer",
      json={
          "offer_id": cheapest["offer_id"],
          "ssh_public_key": "ssh-ed25519 AAAA... your-key",
      },
      headers=headers,
  ).json()
  print(f"Status: {result['status']}")
  ```

  ```typescript TypeScript theme={null}
  const result = await fetch("https://supply-api.compute-desk.com/procure_offer", {
    method: "POST",
    headers: { ...headers, "Content-Type": "application/json" },
    body: JSON.stringify({
      offer_id: cheapest.offer_id,
      ssh_public_key: "ssh-ed25519 AAAA... your-key",
    }),
  }).then(r => r.json()) as any;
  console.log(`Status: ${result.status}`);
  ```
</CodeGroup>

Provisioning is asynchronous. The response returns a status — poll until ready.

## Step 4: Poll until ready

<CodeGroup>
  ```bash curl theme={null}
  curl https://supply-api.compute-desk.com/offers/YOUR_OFFER_ID/status \
    -H "Authorization: Bearer $TOKEN"
  ```

  ```python Python theme={null}
  import time

  offer_id = cheapest["offer_id"]
  while True:
      status = requests.get(
          f"https://supply-api.compute-desk.com/offers/{offer_id}/status",
          headers=headers,
      ).json()
      print(f"Status: {status['procurement_status']}")
      if status["procurement_status"] == "ready":
          instance = status["instances"][0]
          print(f"IP: {instance['external_ip']}")
          print(f"SSH: {instance['ssh_command']}")
          break
      if status["procurement_status"] == "failed":
          raise RuntimeError(status.get("failure_reason"))
      time.sleep(15)
  ```

  ```typescript TypeScript theme={null}
  const offerId = cheapest.offer_id;
  while (true) {
    const status = await fetch(
      `https://supply-api.compute-desk.com/offers/${offerId}/status`,
      { headers }
    ).then(r => r.json()) as any;
    console.log(`Status: ${status.procurement_status}`);
    if (status.procurement_status === "ready") {
      const instance = status.instances[0];
      console.log(`IP: ${instance.external_ip}`);
      console.log(`SSH: ${instance.ssh_command}`);
      break;
    }
    if (status.procurement_status === "failed") {
      throw new Error(status.failure_reason);
    }
    await new Promise(r => setTimeout(r, 15000));
  }
  ```
</CodeGroup>

When `procurement_status` is `"ready"`, you'll see `instances` with `external_ip` and `ssh_command`.

## Step 5: Connect

Use the private key that corresponds to the public key you provided in Step 3:

```bash theme={null}
ssh -i ~/.ssh/your_private_key root@INSTANCE_IP
```

## Step 6: Clean up

<CodeGroup>
  ```bash curl theme={null}
  # List resources for this offer
  curl "https://supply-api.compute-desk.com/resources?offer_id=YOUR_OFFER_ID" \
    -H "Authorization: Bearer $TOKEN"

  # Delete the resource
  curl -X DELETE "https://supply-api.compute-desk.com/resources/RESOURCE_ID?force=true" \
    -H "Authorization: Bearer $TOKEN"
  ```

  ```python Python theme={null}
  # List resources for this offer
  resources = requests.get(
      f"https://supply-api.compute-desk.com/resources?offer_id={offer_id}",
      headers=headers,
  ).json()["resources"]

  # Delete each resource
  for r in resources:
      rid = r["resource_id"]
      requests.delete(
          f"https://supply-api.compute-desk.com/resources/{rid}?force=true",
          headers=headers,
      )
      print(f"Deleted {rid}")
  ```

  ```typescript TypeScript theme={null}
  // List resources for this offer
  const resources = await fetch(
    `https://supply-api.compute-desk.com/resources?offer_id=${offerId}`,
    { headers }
  ).then(r => r.json()) as any;

  // Delete each resource
  for (const r of resources.resources) {
    await fetch(
      `https://supply-api.compute-desk.com/resources/${r.resource_id}?force=true`,
      { method: "DELETE", headers }
    );
    console.log(`Deleted ${r.resource_id}`);
  }
  ```
</CodeGroup>

<Note>
  For a complete, copy-paste-ready script that handles the full lifecycle, see the [Full Example](/guides/full-example).
</Note>
