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

# Buyer workflow

> State demand from your own planning system, follow it to an introduction, and hand off to the dashboard.

A typical buyer integration keeps GPU Outlet in sync with a planning system that already knows what capacity is needed and when. It needs `requests:write`, `requests:read` and `introductions:read`, and `introductions:write` if it also confirms readiness.

<Steps>
  <Step title="Read the market, including capacity being auctioned">
    `GET /radar/nodes` with `radar:read` lists the market. Each node carries an `auction` field: `null` when nothing is being auctioned on it, and otherwise the lot that has not closed yet — its `lot_id`, `format`, `ends_at`, `reserve_cents`, `bid_count` and `current_bid_cents`.

    `current_bid_cents` is the leading bid, and only on an `open` lot that has drawn one. It is always `null` on a `sealed` lot before the close, for every reader including the lot's own seller. Read it together with `format` and `bid_count`: an absent amount means "sealed" or "nobody has bid", never "we did not send it".

    Bidding is not available over the partner API, and a decided lot's outcome is not either. Both are in the dashboard. See [Bidding](/buying/bidding).
  </Step>

  <Step title="Create a request when demand changes">
    `POST /requests` with `requests:write`. Send an `Idempotency-Key` on every write. See [Idempotency](/api/idempotency). One of `endsAt` or `durationMonths` is required.

    ```bash theme={null}
    curl -X POST https://api.gpuoutlet.ai/v1/requests \
      -H "Authorization: Bearer gpk_..." \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: 8f14e45f-ceea-467e-adc2-fb8c3f9f3e0a" \
      -d '{
        "gpuModel": "H100",
        "gpusPerNode": 8,
        "nodes": 4,
        "region": "us-east",
        "startsAt": "2026-10-01T00:00:00.000Z",
        "durationMonths": 6,
        "budgetMonthlyCents": 1200000,
        "currency": "USD",
        "notes": "Training run, flexible on exact start date"
      }'
    ```

    A malformed specification fails with [`request_invalid`](/api/errors#request_invalid). `problems` lists every invalid field, so fix them together instead of retrying field by field.
  </Step>

  <Step title="Keep it up to date while it is open">
    `PATCH /requests/{id}` replaces the specification. This works only while the request's `status` is `open`. Once the GPU Outlet team offers it to a seller, `status` becomes `matched` and the request is frozen:

    ```json theme={null}
    {
      "error": {
        "type": "invalid_request_error",
        "code": "request_not_editable",
        "message": "This request can no longer be edited: it has been matched to a seller or closed. `current` carries its status. State new demand as a new request instead.",
        "doc_url": "https://docs.gpuoutlet.ai/api/errors#request_not_editable",
        "request_id": "a1b2c3d4-...",
        "current": "matched"
      }
    }
    ```

    If your demand changes after a match, close the old request and create a new one.
  </Step>

  <Step title="Close it when demand goes away">
    `POST /requests/{id}/close` from either `open` or `matched`. Closing is final. A request cannot be deleted or reopened.

    ```bash theme={null}
    curl -X POST https://api.gpuoutlet.ai/v1/requests/b6b6f6b0-6e0a-4e0a-9b0a-6f0a4e0a9b0a/close \
      -H "Authorization: Bearer gpk_..." \
      -H "Idempotency-Key: 3c9e6f1a-2b4d-4e5f-8a9b-1c2d3e4f5a6b"
    ```
  </Step>

  <Step title="Poll for introductions">
    Once a seller accepts a match in the dashboard, both companies are introduced. Poll with `introductions:read` and `side=buyer`:

    ```bash theme={null}
    curl "https://api.gpuoutlet.ai/v1/introductions?side=buyer&limit=50" \
      -H "Authorization: Bearer gpk_..."
    ```

    `GET /introductions/{id}` reads a single one the same way. See [Pagination](/api/pagination) for `meta.nextCursor`.

    The introduction carries the seller's `legalName` and `country`, its `reference` (for example `GO-20260917-K7M2QX`), the frozen demand and listing, `feeBasisPoints`, and `readiness` timestamps. It does not carry the seller's contacts. The seller reaches out to your company's contacts.
  </Step>

  <Step title="Confirm you are ready">
    `POST /introductions/{id}/ready` with `introductions:write`, once your company is ready to proceed. This needs a trader, an authorized signatory or an owner. A viewer's key gets `forbidden_role`.

    ```bash theme={null}
    curl -X POST https://api.gpuoutlet.ai/v1/introductions/9d8c7b6a-5f4e-3d2c-1b0a-9f8e7d6c5b4a/ready \
      -H "Authorization: Bearer gpk_..." \
      -H "Idempotency-Key: 1a2b3c4d-5e6f-7890-ab12-cd34ef567890"
    ```

    ```json Response theme={null}
    {
      "sellerReadyAt": null,
      "buyerReadyAt": "2026-09-17T17:00:00.000Z"
    }
    ```

    If the introduction is no longer active, for example because it was released, this fails with [`introduction_not_active`](/api/errors#introduction_not_active).
  </Step>

  <Step title="What continues in the dashboard">
    Once both sides are ready, the seller sends a deal invoice in the dashboard. Your company pays it directly to the seller, outside GPU Outlet. Deal invoices and receipts are available only in the dashboard. Sign in to see and act on them. See [Buyer introductions](/buying/introductions).
  </Step>
</Steps>

## Related

<CardGroup cols={2}>
  <Card title="Seller workflow" icon="server" href="/api/workflows/sellers">
    What happens on the other side of the same introduction.
  </Card>

  <Card title="Idempotency" icon="rotate" href="/api/idempotency">
    Safe retries for the writes in this workflow.
  </Card>

  <Card title="Errors" icon="triangle-exclamation" href="/api/errors">
    `request_not_editable`, `request_invalid`, `introduction_not_active`.
  </Card>

  <Card title="Authentication" icon="key" href="/api/authentication">
    Scopes and company context this workflow relies on.
  </Card>
</CardGroup>


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