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

# Migrating from RunPod

> Keep your RunPod client. Point it at api.aireserve.com with a RunPod credential from the AI Reserve portal — every call passes through unchanged to the RunPod organization contracted for you.

AI Reserve serves the **RunPod API** at `https://api.aireserve.com`. A RunPod
client whose base URL is repointed here — the REST v2 TypeScript SDK, the
`runpod` Python package, the Serverless job SDKs, the local RunPod MCP server,
`runpodctl` for part of its surface, a generated OpenAPI client, curl — keeps
working after **two settings change**: the base URL and the key. The gateway
authenticates your AI Reserve credential, swaps it for the upstream key of the
RunPod organization contracted for you, forwards the request exactly as you
sent it, and relays RunPod's answer exactly as RunPod gave it. There is no
operation allowlist: the whole of RunPod REST v2, the GraphQL API and
Serverless job invocation pass through, minus a short list of
tenancy-protecting denials described under
[What AI Reserve enforces](#what-ai-reserve-enforces).

This endpoint is for organizations with a RunPod contract that AI Reserve has
**assigned** to them: a RunPod Organization provisioned under that contract and
recorded against your AI Reserve organization. Without an assignment every
call is refused before it reaches RunPod.

| RunPod setting | AI Reserve value |
| - | - |
| `RUNPOD_API_BASE_URL` (REST v2 + GraphQL; default `https://api.runpod.io`) | `https://api.aireserve.com` — **no `/v2` suffix**; the client adds it, so requests become `https://api.aireserve.com/v2/pods` |
| `RUNPOD_ENDPOINT_BASE_URL` (Serverless jobs; default `https://api.runpod.ai/v2`) | `https://api.aireserve.com/serverless/v2` |
| GraphQL endpoint (`https://api.runpod.io/graphql`) | `https://api.aireserve.com/graphql` |
| `RUNPOD_API_KEY` from the RunPod console | A **RunPod credential** (`aireserve_api_…`) created under **Compute › RunPod** in the AI Reserve portal. Same `Authorization: Bearer` header. An ordinary inference key is refused |

> [!NOTE]
>
> **This is a passthrough, not a translation.** Resource ids, request bodies, response shapes, pagination,
> `RateLimit` headers, `application/problem+json` errors, SSE log streams — all RunPod's own. Resources you create
> live in the RunPod organization contracted for you, so ids from a personal RunPod account do not carry over; RunPod
> does not move personal resources into an organization on its own
> ([Access](https://docs.runpod.io/organizations/orgs-access)).

## How tenancy works

The isolation is RunPod's, not a filter in the gateway.

* **The organization is the tenancy wall.** RunPod Organizations are its
  enterprise account model: "an organization is a first-class entity that owns
  all resources independent of any individual member, including compute,
  storage, secrets, and templates", and "A user belongs to at most one
  organization"
  ([Organizations](https://docs.runpod.io/organizations/orgs-overview)). The
  upstream key AI Reserve holds for you belongs to a member of **your**
  organization and to nothing else, so nothing outside it is reachable. RunPod
  notes that "Organizations are currently in beta. Runpod provisions
  organization accounts and enables them for your account"
  ([Organizations](https://docs.runpod.io/organizations/orgs-overview)) — which
  is why AI Reserve arranges the organization under the contract rather than
  creating it through an API.
* **The Dev role bounds management.** The member that minted the upstream key
  holds RunPod's **Dev** role: "Full compute access with no billing or member
  management. Devs can deploy Pods, create Serverless endpoints, manage network
  volumes, Instant Clusters, and templates. They cannot view billing, manage
  cost centers, or manage members or groups"
  ([Roles](https://docs.runpod.io/organizations/org-roles)).
* **The Restricted key bounds permission.** RunPod API keys are created with
  **All**, **Restricted** or **Read Only** access; a Restricted key sets
  **None**, **Restricted**, **Read/Write** or **Read Only** per RunPod API
  ([API keys](https://docs.runpod.io/get-started/credentials#api-keys)). Your
  read/write credential maps to a Restricted key with Read/Write on the compute
  APIs; your read-only credential maps to a Read Only key. RunPod enforces
  these at the source: "Keys are scoped to the permissions granted when
  created; requests may return `403` when a valid key lacks access to the
  requested resource or action" (security scheme in
  [`openapi.json`](https://api.runpod.io/v2/openapi.json)).
* **Visibility follows the member.** "By default, a member can only see
  resources they created themselves. When a resource is assigned to a group,
  all members of that group can see it, regardless of who created it"
  ([Groups](https://docs.runpod.io/organizations/orgs-groups)). Everything you
  create through this endpoint is created by that member and is visible to
  you. A resource created directly in the RunPod console by someone else
  appears through this endpoint only once an organization admin assigns it to
  a group that member belongs to. Templates are listed "owned by the
  authenticated user (including team/organization-scoped ones)"
  ([`GET /v2/templates`](https://docs.runpod.io/api-reference-v2/templates/list-templates)).

The gateway adds defense in depth on top — the denials below — but it never
needs to know which resource is whose.

## Get a RunPod credential

A RunPod credential is an AI Reserve API key bound to a RunPod permission
level. You never see a RunPod key.

1. In the portal open **Compute › RunPod**. The page shows the RunPod
   organization assigned to you (id and name, as RunPod reported them when AI
   Reserve verified the upstream key) and your existing credentials. If no
   organization is assigned yet, creating a credential is refused with
   "No RunPod organization is assigned to your organization yet. Contact AI
   Reserve to assign your contracted RunPod organization."
2. Choose a name and a permission:
   * **read-only** — RunPod's **Read Only** level. Lists and reads only:
     `GET`/`HEAD` on REST v2 and Serverless, queries only on GraphQL. Any
     mutation is refused by the gateway with
     `This RunPod credential is read-only.` before it reaches RunPod.
   * **read/write** — RunPod's **Restricted** level with Read/Write on pods,
     Serverless, templates, volumes, clusters and registries. Resource
     mutations pass; account and organization management does not (below).
3. Copy the key. It is shown **once**; afterwards only its prefix and suffix
   are displayed. Organization admins create and revoke credentials; revoking
   one stops every client using it until you create another.

Credentials carry the **RunPod** badge on the API Keys page and cannot be
edited into another category. A key created anywhere else — an ordinary
inference key, a customer key, a CI key — is refused on this endpoint with
`403` and the detail `This API key is not a RunPod credential. Create one under
Compute › RunPod in the AI Reserve portal.` Keyless (OIDC) callers get the
same answer: the RunPod surface is key-only.

## Which RunPod clients work

| Client | Works | How |
| - | - | - |
| **`@runpod/typescript-api-sdk`** (`createRunpodClient`) | ✅ | Reads `RUNPOD_API_BASE_URL` + `RUNPOD_API_KEY` (or `createRunpodClient({ baseUrl, apiKey })`). Base URL without `/v2`; the SDK's paths carry it. |
| **`runpod` Python package, 2.0.0rc1 and later** — pods, templates, endpoints, volumes | ✅ | REST v2 control plane. Reads `RUNPOD_API_BASE_URL`, `RUNPOD_ENDPOINT_BASE_URL` and `RUNPOD_API_KEY` from the environment. |
| **`runpod` Python package, 1.12.0 (current stable)** — pods, templates, endpoints | ⚠️ | GraphQL-only control plane at `${RUNPOD_API_BASE_URL}/graphql`. Reads the two URL variables but **not** `RUNPOD_API_KEY`: set `runpod.api_key = "aireserve_api_…"` in code, or store it once with `runpod config` ([SkyPilot integration](https://docs.runpod.io/integrations/skypilot)). GraphQL is deprecated and "will be retired in early 2027" ([GraphQL API](https://docs.runpod.io/sdks/graphql/configurations)). |
| **`runpod.Endpoint`** Serverless jobs (`run_sync`, `run`, `status`, `stream`, `health`, `purge_queue`), any version | ✅ | `RUNPOD_ENDPOINT_BASE_URL=https://api.aireserve.com/serverless/v2`, key as in the row for your version. |
| **`runpodctl`** | ⚠️ | Partial. Set `RUNPOD_GRAPHQL_URL`, `RUNPOD_REST_V2_URL`, `RUNPOD_INVOKE_URL` and `RUNPOD_API_KEY`. **Works:** `gpu list`, `user`, `ssh list-keys`, `ssh connect`, GPU `pod create`, `pod logs`, `serverless logs`, `serverless run`, `serverless status`, `serverless health`. **Does not work:** `pod list`, `pod get`, `pod stop`, `pod start`, `pod restart`, `pod reset`, `pod delete`, `pod update`, CPU `pod create`, `serverless create`, `serverless list`, `serverless get`, `serverless update`, `serverless delete`, `template`, `network-volume`, `registry`, `billing` — these call REST v1 (`rest.runpod.io/v1`), which is not served and which RunPod retires on **November 15, 2026** ([REST API v1](https://docs.runpod.io/api-reference/overview)). `ssh add-key` is also refused: it is the GraphQL `updateUserSettings` mutation (see below); manage SSH keys through `PUT /v2/account/ssh-keys` instead. |
| **`@runpod/mcp-server`**, local (Claude Code, Codex CLI, Cursor, Claude Desktop, …) | ✅ | Four host variables plus the key: `RUNPOD_API_BASE_URL` (REST v2 tools), `RUNPOD_SERVERLESS_API_URL` (job tools), `RUNPOD_PUBLIC_GRAPHQL_URL` and `RUNPOD_AUTHED_GRAPHQL_URL` (GraphQL tools), `RUNPOD_API_KEY`. Setting only `RUNPOD_API_BASE_URL` leaves the GraphQL and job tools pointed at RunPod directly. |
| **Hosted RunPod MCP server** (`https://mcp.getrunpod.io/`) | ❌ | RunPod's hosted service calls RunPod's API itself and has no base-URL setting; it cannot be pointed at AI Reserve ([MCP servers](https://docs.runpod.io/get-started/mcp-servers)). Use the local server. |
| **`runpod-sdk`** (JavaScript Serverless SDK) | ✅ | Constructor option: `runpodSdk(apiKey, { baseUrl: "https://api.aireserve.com/serverless/v2" })`. No environment variable. |
| **Go SDK v2** (`github.com/runpod/go-sdk/v2`) | ✅ | `runpod.New(runpod.WithBaseURL("https://api.aireserve.com"))`; key from `RUNPOD_API_KEY` or `runpod.WithAPIKey`. `New()` does not read `RUNPOD_API_BASE_URL`. |
| **Go Serverless SDK** (`github.com/runpod/go-sdk/pkg/sdk/endpoint`) | ✅ | `Option{ EndpointId, EndpointUrl }` with `EndpointUrl` = `https://api.aireserve.com/serverless/v2`. |
| **Raw REST v2 / GraphQL** (`curl`, your own HTTP client, generated clients from `api.aireserve.com/v2/openapi.json`) | ✅ | Replace the host. RunPod's documented GraphQL form, "your API key included as a query parameter" ([GraphQL API](https://docs.runpod.io/sdks/graphql/configurations)), is accepted: a `?api_key=aireserve_api_…` is lifted into the Authorization header before routing and never forwarded. |
| **OpenAI-compatible vLLM endpoints** (`…/v2/<endpoint-id>/openai/v1`) | ✅ | Base URL `https://api.aireserve.com/serverless/v2/<endpoint-id>/openai/v1` ([OpenAI compatibility](https://docs.runpod.io/serverless/vllm/openai-compatibility)). |
| **REST v1** (`rest.runpod.io/v1`) | ❌ | Not mounted. RunPod retires it on November 15, 2026 and offers `/runpod:migrate rest` to move an integration to v2 ([REST API v1](https://docs.runpod.io/api-reference/overview)). |
| **Per-endpoint load-balancer hostnames** (`https://<endpoint-id>.api.runpod.ai/...`) | ❌ | Hostname-addressed, not path-addressed; call those endpoints directly. |

## What to change

```diff Shell theme={"dark"}
-export RUNPOD_API_KEY="rpa_…"
+export RUNPOD_API_BASE_URL="https://api.aireserve.com"                    # no /v2 suffix
+export RUNPOD_ENDPOINT_BASE_URL="https://api.aireserve.com/serverless/v2"  # Serverless jobs only
+export RUNPOD_API_KEY="aireserve_api_…"                                   # your RunPod credential
```

```ts TypeScript SDK theme={"dark"}
import { createRunpodClient } from "@runpod/typescript-api-sdk";

// Nothing to change in code: the client reads RUNPOD_API_BASE_URL and RUNPOD_API_KEY.
const runpod = createRunpodClient();

const { data: pod } = await runpod.POST("/v2/pods", {
  body: {
    name: "comfyui-1",
    image: "ghcr.io/acme/comfyui:latest",
    gpu: { id: "NVIDIA A40", count: 1 },
    disk: 50,
    ports: ["8188/http", "22/tcp"],
  },
});
await runpod.POST("/v2/pods/{id}/action", { params: { path: { id: pod!.id } }, body: { action: "stop" } });
await runpod.DELETE("/v2/pods/{id}", { params: { path: { id: pod!.id } } });
```

```python Python (runpod ≥ 2.0.0rc1) theme={"dark"}
import os, runpod

# Nothing to change in code: 2.0 reads RUNPOD_API_KEY, RUNPOD_API_BASE_URL
# and RUNPOD_ENDPOINT_BASE_URL from the environment.
pods = runpod.get_pods()

endpoint = runpod.Endpoint(os.environ["ENDPOINT_ID"])          # Serverless jobs
print(endpoint.run_sync({"prompt": "Hello, world!"}, timeout=60))
```

```python Python (runpod 1.12.0) theme={"dark"}
import os, runpod

# 1.12 reads RUNPOD_API_BASE_URL and RUNPOD_ENDPOINT_BASE_URL, but NOT
# RUNPOD_API_KEY. Set the credential in code (or once with `runpod config`):
runpod.api_key = os.environ["RUNPOD_API_KEY"]

pods = runpod.get_pods()                                       # GraphQL query
pod = runpod.create_pod("comfyui-1", "ghcr.io/acme/comfyui:latest", "NVIDIA A40")  # read/write credential
runpod.stop_pod(pod["id"])

endpoint = runpod.Endpoint(os.environ["ENDPOINT_ID"])          # Serverless jobs
print(endpoint.run_sync({"prompt": "Hello, world!"}, timeout=60))
```

```bash runpodctl theme={"dark"}
export RUNPOD_GRAPHQL_URL=https://api.aireserve.com/graphql           # config: apiUrl
export RUNPOD_REST_V2_URL=https://api.aireserve.com/v2                 # config: restV2ApiUrl
export RUNPOD_INVOKE_URL=https://api.aireserve.com/serverless/v2       # config: invokeUrl
export RUNPOD_API_KEY=aireserve_api_…

runpodctl gpu list                                                     # GraphQL
runpodctl pod create --template-id runpod-torch-v21 --gpu-id "NVIDIA RTX 4090"   # GPU pods: GraphQL
runpodctl pod logs <pod-id>                                            # REST v2
runpodctl serverless run <endpoint-id> --input '{"prompt":"hi"}'       # Serverless invoke
# pod list/stop/start/delete, serverless create/list, template, network-volume,
# registry and billing use REST v1 and are NOT served — use the REST v2 SDK or curl.
```

```bash MCP server (Claude Code) theme={"dark"}
claude mcp add runpod --scope user \
  -e RUNPOD_API_BASE_URL=https://api.aireserve.com \
  -e RUNPOD_SERVERLESS_API_URL=https://api.aireserve.com/serverless/v2 \
  -e RUNPOD_PUBLIC_GRAPHQL_URL=https://api.aireserve.com/graphql \
  -e RUNPOD_AUTHED_GRAPHQL_URL=https://api.aireserve.com/graphql \
  -e RUNPOD_API_KEY=aireserve_api_… \
  -- npx -y @runpod/mcp-server@latest
```

```js JavaScript (runpod-sdk) theme={"dark"}
import runpodSdk from "runpod-sdk";

const runpod = runpodSdk(process.env.RUNPOD_API_KEY, {
  baseUrl: "https://api.aireserve.com/serverless/v2",   // default is https://api.runpod.ai/v2
});
const endpoint = runpod.endpoint(process.env.ENDPOINT_ID);
const result = await endpoint.runSync({ input: { prompt: "Hello, world!" } });
```

```go Go (SDK v2) theme={"dark"}
import runpod "github.com/runpod/go-sdk/v2"

// Key from RUNPOD_API_KEY (or runpod.WithAPIKey). New() does not read RUNPOD_API_BASE_URL,
// so the base URL is an option:
client, err := runpod.New(runpod.WithBaseURL("https://api.aireserve.com"))
```

```go Go (Serverless SDK) theme={"dark"}
import (
	"os"

	"github.com/runpod/go-sdk/pkg/sdk/config"
	rpEndpoint "github.com/runpod/go-sdk/pkg/sdk/endpoint"
)

apiKey := os.Getenv("RUNPOD_API_KEY")
endpointID := os.Getenv("ENDPOINT_ID")
endpointURL := "https://api.aireserve.com/serverless/v2"

endpoint, err := rpEndpoint.New(
	&config.Config{ApiKey: &apiKey},
	&rpEndpoint.Option{EndpointId: &endpointID, EndpointUrl: &endpointURL},
)
```

```bash curl theme={"dark"}
# REST v2
curl https://api.aireserve.com/v2/catalog/gpus -H "Authorization: Bearer $RUNPOD_API_KEY"
curl -X POST https://api.aireserve.com/v2/pods \
  -H "Authorization: Bearer $RUNPOD_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"comfyui-1","image":"ghcr.io/acme/comfyui:latest","gpu":{"id":"NVIDIA A40","count":1},"disk":50}'

# GraphQL (header, or RunPod's documented ?api_key= form — the key is lifted into the header, never forwarded)
curl -X POST https://api.aireserve.com/graphql -H "Authorization: Bearer $RUNPOD_API_KEY" \
  -H "Content-Type: application/json" -d '{"query":"query { myself { id } }"}'

# Serverless job
curl -X POST https://api.aireserve.com/serverless/v2/$ENDPOINT_ID/runsync \
  -H "Authorization: Bearer $RUNPOD_API_KEY" -H "Content-Type: application/json" \
  -d '{"input":{"prompt":"Hello, world!"}}'

# Pod logs (SSE)
curl -N "https://api.aireserve.com/v2/pods/$POD_ID/logs?tail=100" -H "Authorization: Bearer $RUNPOD_API_KEY"
```

## What AI Reserve enforces

Every refusal is RunPod-shaped `application/problem+json` — the
`{ title, status, detail }` envelope RunPod's own errors use — and names its
cause in `detail`, so the SDKs surface it unchanged:

```json theme={"dark"}
{ "title": "Forbidden", "status": 403, "detail": "This RunPod credential is read-only." }
```

* **Your organization's policies.** The credential is checked exactly as on
  every AI Reserve endpoint: paused keys (`401`,
  `This key is paused — an admin can resume it from the API Keys page.`),
  invalid keys (`401`, `Invalid API key.`), per-key IP allowlists and
  organization network policies (`403`), and rate limits (`429` with
  `Retry-After`). RunPod calls never touch the token wallet: a wallet outage or
  a zero token balance cannot turn a valid RunPod request into a `402` or
  `503`.
* **Tenancy.** The credential is resolved to your assignment on every request
  (memoised for 30 seconds). Refusals, all `403` and all before any upstream
  call:
  * `This API key is not a RunPod credential. Create one under Compute › RunPod in the AI Reserve portal.`
  * `No RunPod organization is assigned to this AI Reserve organization. Contact AI Reserve to assign your contracted RunPod organization.`
  * `The assigned RunPod organization has no upstream credential at this key's permission level yet. Contact AI Reserve.`
    — for example a read-only credential when AI Reserve holds only a
    read/write upstream key for your organization.
  * `503` `The RunPod credential for this organization could not be loaded. Retry; contact AI Reserve if it persists.`
    — a transient lookup failure, or a stored key the gateway cannot decrypt.
    Never a fallback to any other key.
* **Read-only credentials.** `GET`, `HEAD` and `OPTIONS` on REST v2 and
  Serverless, queries on GraphQL. Anything else is `403`
  `This RunPod credential is read-only.`
* **The account secrets store is denied for every credential.** Every method
  on `/v2/account/secrets` and `/v2/account/secrets/*` answers `403`
  `The RunPod account secrets store is not available through AI Reserve. Registries and pod secrets are.`
  RunPod tags both the secrets store and container registries with the same
  `secrets` scope (`x-runpod-scope` in
  [`openapi.json`](https://api.runpod.io/v2/openapi.json)), so a key that can
  reach your private registries can also read the organization's secret
  store; the gateway closes that path. Registry credentials
  (`/v2/registries*`) and secrets passed in a pod's environment are
  unaffected.
* **Account, organization and API-key management is denied on GraphQL for
  every credential.** A GraphQL document whose top-level mutation fields
  include any of `createApiKey`, `updateApiKey`, `deleteApiKey`,
  `createSharedApiKey`, `createFlashAuthRequest`,
  `organizationInviteCreate`, `organizationInviteAccept`,
  `organizationInviteDelete`, `organizationMembershipUpdate`,
  `organizationMembershipDelete`, `organizationUpdate`, `groupCreate`,
  `groupUpdate`, `groupDelete`, `teamCreate`, `teamUpdate`, `teamDelete`,
  `teamInviteCreate`, `teamInviteDelete`, `teamJoin`, `teamMembershipUpdate`,
  `teamMembershipDelete`, `updateUserSettings`, `updateUserInformation`,
  `deleteUser`, `setDefaultPaymentMethod` or `deletePaymentMethod` answers
  `403`
  `Account, organization and API-key management mutations are not available through AI Reserve.`
  Aliases and variables do not get around the check, and a mutation document
  the gateway cannot parse is refused the same way. The check is also
  deliberately conservative: a mutation whose top-level selection uses a
  fragment spread, an inline fragment, or a directive, or whose operation
  head carries anything other than variable definitions, is refused as well,
  because the gateway cannot vouch for where such a document executes (a
  denied field inside any fragment definition is refused by name). Write
  mutations the way RunPod's own clients do — named fields with arguments
  and nested selections — and they pass; fragments and directives below the
  top level are fine. Resource
  mutations — pods, endpoints, templates, volumes, registries, clusters — pass.
  The RunPod GraphQL API itself is deprecated and "will be retired in early
  2027" ([GraphQL API](https://docs.runpod.io/sdks/graphql/configurations)).
* **Headers.** Your `Authorization` and `x-api-key` are replaced by the
  upstream key; `X-Team-Id` is dropped (the upstream key is already bound to
  your organization); `Accept-Encoding` is pinned to `identity` so RunPod's
  bytes are the bytes relayed. `Idempotency-Key`, `Last-Event-ID`,
  `x-runpod-*` and SDK user agents go through.
* **A request log.** Each forwarded call is recorded with method, path (any
  credential-looking query value masked), RunPod's `x-request-id`, upstream
  status, `RateLimit`, byte counts, time-to-headers, duration, outcome, your
  key id, and the assignment, credential and organization ids it resolved to.
  Refusals are recorded with their outcome before any upstream request.
  Neither includes bodies or credentials.
* **Nothing else.** No request rewriting, no field validation, no response
  filtering. An error from RunPod is RunPod's error, relayed with RunPod's
  status. If RunPod answers `401` to a forwarded call, the upstream key was
  disabled or revoked in the RunPod console; the answer is relayed as-is and
  the credential is flagged for AI Reserve to rotate.
* **Transport.** RunPod unreachable → `503`; no response headers within the
  time-to-headers bound (sized for pod placement and `/runsync?wait=`) →
  `504`; a stream that has started is never cut by that bound.

## Limits

* **A fresh organization, driven through the API.** Pods, volumes, templates,
  registries, endpoints and SSH keys created through this endpoint belong to
  the RunPod organization contracted for you. You do not get RunPod console
  access to it through AI Reserve, and resources from a previous RunPod
  account are not migrated.
* **Usage is metered hourly into your AI Reserve ledger.** RunPod organizations
  "are billed on a post-paid invoice model"
  ([Billing](https://docs.runpod.io/organizations/orgs-billing)); the
  commitment and any overage sit on your AI Reserve order. Every hour, AI
  Reserve reads RunPod's own billing history for your organization and books
  each pod, network volume, cluster and serverless endpoint hour to your
  wallet at RunPod's metered amount. Each hour appears as its own line in
  **Observe › Event Log** and **Financials** (model `runpod:pod`,
  `runpod:network_volume`, `runpod:cluster` or `runpod:serverless`, with the
  RunPod resource id in its details). Hours settle about two hours behind
  real time. `GET /v2/billing/*` passes through and shows the same figures —
  RunPod's rule is that "Dev members see their own usage only"
  ([Billing](https://docs.runpod.io/organizations/orgs-billing)), and the
  member behind your credential is exactly what you created through AI Reserve.
* **Capacity is RunPod's decision.** The gateway does not reserve cards or
  rewrite GPU choices; RunPod places the request under the organization's
  contract. Requests outside the committed hardware or quantity still pass
  through and may be billed as overage by RunPod.
* **No account secrets store, no management mutations** (above). Manage SSH
  keys through `PUT /v2/account/ssh-keys` rather than the GraphQL
  `updateUserSettings` mutation.
* **RunPod's own sunsets apply.** REST v1 is not mounted and retires on
  November 15, 2026 ([REST API v1](https://docs.runpod.io/api-reference/overview));
  GraphQL retires in early 2027
  ([GraphQL API](https://docs.runpod.io/sdks/graphql/configurations)). Move
  GraphQL and v1 integrations to REST v2 — RunPod's
  [migration guide](https://docs.runpod.io/api-reference-v2/migrate-from-v1)
  and `/runpod:migrate` cover both.
* **Serverless and Instant Clusters** are RunPod products reached through this
  endpoint; they are not AI Reserve catalog products and carry no AI Reserve
  quote or price ceiling. For multi-node training with a quote and a price
  ceiling, use [AI Reserve clusters](/gpu-infrastructure/clusters).

Ready for more than a lift-and-shift? The
[standard GPU API](/gpu-infrastructure/quickstart) adds quotes with price
ceilings, provider-free capability launch, persistent storage in the same
request, and the `aireserve` CLI.


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