> ## Documentation Index
> Fetch the complete documentation index at: https://runpod-b18f5ded-seo-aeo-docs-config.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a cluster

> Creates a multi-node cluster. `compute` sets the homogeneous
pod shape; the container configuration applies to every pod and can be spread
from a template response.




## OpenAPI

````yaml post /v2/clusters
openapi: 3.1.0
info:
  title: Runpod REST API
  version: 2.0.0
  description: Runpod public REST API — v2
servers:
  - url: https://api.runpod.io
    description: Runpod API v2 production server
security:
  - bearerAuth: []
tags:
  - name: Account
    description: Account-scoped settings and primitives (SSH public keys).
  - name: Pods
    description: GPU and CPU pod lifecycle, configuration, actions, and log streaming.
  - name: Serverless
    description: >-
      Serverless endpoint lifecycle, worker visibility, releases, and worker log
      streaming.
  - name: Templates
    description: Reusable pod and endpoint configuration templates.
  - name: Network Volumes
    description: Persistent network storage volumes for workloads.
  - name: Registries
    description: Container registry credentials used to pull private images.
  - name: Catalog
    description: Available GPU, CPU, data center, and public template catalog metadata.
  - name: Billing
    description: Billing history and usage cost records across resource types.
paths:
  /v2/clusters:
    post:
      tags:
        - Clusters
      summary: Create a cluster
      description: >
        Creates a multi-node cluster. `compute` sets the homogeneous

        pod shape; the container configuration applies to every pod and can be
        spread

        from a template response.
      operationId: createCluster
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateClusterRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Cluster'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          $ref: '#/components/responses/ForbiddenError'
        '422':
          $ref: '#/components/responses/UnprocessableEntityError'
        '429':
          $ref: '#/components/responses/TooManyRequestsError'
        default:
          description: Error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    CreateClusterRequest:
      allOf:
        - $ref: '#/components/schemas/BaseContainerConfig'
        - type: object
          required:
            - name
            - type
            - compute
          description: >
            Request body for creating a cluster. `compute` defines the

            homogeneous pod shape; the container configuration (image, env,
            ports,

            …) applies to every pod and can be spread from a template response.

            Private registries are not yet supported for clusters — there is no

            `registry` field here, unlike the other create requests.
          properties:
            name:
              type: string
              minLength: 1
              examples:
                - my-training-cluster
            type:
              $ref: '#/components/schemas/ClusterType'
            compute:
              $ref: '#/components/schemas/ClusterCompute'
            startSsh:
              type: boolean
              default: false
              description: >-
                Provision SSH access on every member pod: injects a PUBLIC_KEY
                environment variable carrying your account's registered SSH
                public key. Same semantics as the pod create flag.
            startJupyter:
              type: boolean
              default: false
              description: Start Jupyter on every member pod, as on pod create.
            mounts:
              $ref: '#/components/schemas/Mounts'
            dataCenterIds:
              type: array
              items:
                type: string
              description: |
                Preferred data centers for placement. Omit or pass an empty
                array to let the scheduler choose. A cluster is always placed
                within a single data center.
              example:
                - US-TX-3
      unevaluatedProperties: false
    Cluster:
      type: object
      description: >-
        A cluster. Cluster-level fields describe the identity and homogeneous
        shape; `pods` is a lightweight summary of the members. Fetch the full
        member pods — with their container config, mounts, and runtime state —
        from `GET /v2/clusters/{id}/pods`.
      required:
        - id
        - name
        - type
        - compute
        - pods
        - createdAt
      properties:
        id:
          type: string
          examples:
            - cluster_abc123
        name:
          type: string
          examples:
            - my-training-cluster
        type:
          $ref: '#/components/schemas/ClusterType'
        compute:
          $ref: '#/components/schemas/ClusterCompute'
        template:
          type: string
          description: >-
            ID of the template this cluster's pods were created from; omitted
            when they were not created from one.
          examples:
            - tpl_abc
        dataCenterId:
          type: string
          description: >-
            Data center the cluster is placed in (a cluster is always within a
            single data center). Derived from the member pods; omitted until at
            least one pod is placed.
          examples:
            - US-TX-3
        pods:
          $ref: '#/components/schemas/ClusterPodsSummary'
        network:
          description: >-
            The cluster's overlay network; omitted until the network is
            provisioned.
          allOf:
            - $ref: '#/components/schemas/ClusterNetwork'
        primary:
          description: >-
            The primary (master) node; omitted until a primary pod is placed.
            Its `sshEndpoint` is omitted until that pod is RUNNING with SSH
            exposed.
          allOf:
            - $ref: '#/components/schemas/ClusterPrimary'
        createdAt:
          type: string
          format: date-time
          examples:
            - '2026-06-29T20:00:00Z'
    ErrorResponse:
      type: object
      required:
        - title
        - status
        - detail
      properties:
        title:
          type: string
          description: Short human-readable summary
          examples:
            - Not Found
        status:
          type: integer
          description: HTTP status code
          examples:
            - 404
        detail:
          type: string
          description: Human-readable explanation
          examples:
            - pod not found
        errors:
          type: array
          description: Individual request-validation failures.
          items:
            type: string
          examples:
            - - '$: additional properties ''bogus'' not allowed'
    BaseContainerConfig:
      type: object
      description: >
        Container configuration universal to every containerized resource.
        Compose ContainerConfig instead unless the resource cannot support
        private registries (clusters, until the upstream input accepts a
        registry credential).
      properties:
        image:
          type: string
          description: Docker image reference
          examples:
            - runpod/pytorch:2.8.0-py3.11-cuda12.8.1
        args:
          type: string
          description: Arguments passed to the container entrypoint
          examples:
            - ''
        disk:
          type: integer
          minimum: 1
          description: Container disk in GB (ephemeral, wiped on restart)
          examples:
            - 50
        ports:
          type: array
          description: Exposed ports, formatted as port/protocol
          items:
            type: string
          examples:
            - - 8888/http
              - 22/tcp
        env:
          type: object
          additionalProperties:
            type: string
          description: Environment variables as key-value pairs
          examples:
            - JUPYTER_PASSWORD: hunter2
    ClusterType:
      type: string
      description: >-
        Cluster type. TRAINING is the generic distributed-training cluster;
        SLURM provisions a managed Slurm controller/compute topology; RAY
        provisions a managed Ray head/worker topology; APPLICATION is a general
        multi-node application cluster.
      enum:
        - APPLICATION
        - TRAINING
        - SLURM
        - RAY
      examples:
        - TRAINING
    ClusterCompute:
      type: object
      additionalProperties: false
      description: >-
        The homogeneous compute shape of a cluster. Every pod in the cluster is
        identical: `podCount` pods, each with `gpuCountPerPod` GPUs of type
        `gpuTypeId`. Total GPUs = `podCount` * `gpuCountPerPod`.
      required:
        - gpuTypeId
        - gpuCountPerPod
        - podCount
      properties:
        gpuTypeId:
          type: string
          minLength: 1
          description: >-
            GPU type for every pod in the cluster, as returned by GET
            /v2/catalog/gpus.
          examples:
            - NVIDIA H100 80GB HBM3
        gpuCountPerPod:
          type: integer
          minimum: 1
          description: >-
            Number of GPUs on each pod. Bounded above by the GPU type's
            per-cloud maximum (GpuType.maxCount); the upstream rejects values
            beyond it.
          examples:
            - 8
        podCount:
          type: integer
          minimum: 2
          maximum: 250
          description: Number of pods (nodes) in the cluster.
          examples:
            - 4
    Mounts:
      type: object
      additionalProperties: false
      description: |
        Storage mounts attached to a pod. At-most-one of `persistent` or
        `network` may be set today (mutually exclusive, enforced at the
        handler with 400 if both are present). The `network` field is an
        array for forward compatibility with eventual multi-network-volume
        support, but `maxItems` is 1 today.

        PATCH semantics:
        - Omitting `mounts` or sending `{}` leaves the existing mount
          unchanged.
        - An explicit `network: []` is rejected with 400 (clearing mounts
          is not supported).
        - Mount kind is fixed at create — a PATCH that introduces a kind
          not present at create (persistent on a network pod, network on
          a persistent pod, or any mount on a previously-mountless pod)
          is rejected with 400.
        - The `volumeId` of a network mount is immutable; a PATCH that
          names a different `volumeId` is rejected with 400.
        - Partial mounts are not supported — every mount entry must
          include the full schema (`size` + `path` for persistent,
          `volumeId` + `path` for network). Missing required fields → 422.
      properties:
        persistent:
          $ref: '#/components/schemas/PersistentMount'
        network:
          type: array
          maxItems: 1
          items:
            $ref: '#/components/schemas/NetworkMount'
    ClusterPodsSummary:
      type: object
      additionalProperties: false
      description: >-
        A lightweight summary of a cluster's member pods. Use `GET
        /v2/clusters/{id}/pods` to retrieve the full pod objects.
      required:
        - total
        - byStatus
      properties:
        total:
          type: integer
          description: Number of member pods currently provisioned for the cluster.
          examples:
            - 4
        byStatus:
          type: object
          additionalProperties:
            type: integer
          description: >-
            Member pod counts keyed by pod status (the same values as
            `Pod.status`, e.g. RUNNING, PROVISIONING). Statuses with no pods are
            omitted.
          example:
            RUNNING: 3
            PROVISIONING: 1
    ClusterNetwork:
      type: object
      additionalProperties: false
      description: The cluster's private VXLAN overlay network (shared by all member pods).
      required:
        - cidr
      properties:
        cidr:
          type: string
          description: The overlay network's CIDR block.
          examples:
            - 10.65.0.0/16
        vxlanId:
          type: integer
          description: VXLAN network identifier; omitted until assigned.
          examples:
            - 42
        vxlanPort:
          type: integer
          description: UDP port carrying the VXLAN traffic; omitted until assigned.
          examples:
            - 4789
    ClusterPrimary:
      type: object
      additionalProperties: false
      description: >-
        The cluster's primary (master) node, through which the cluster is
        typically driven. Omitted until a primary pod has been placed.
      required:
        - podId
        - status
      properties:
        podId:
          type: string
          description: ID of the primary member pod.
          examples:
            - pod_node0
        status:
          $ref: '#/components/schemas/PodStatus'
        sshEndpoint:
          type: string
          description: >-
            Public SSH endpoint (`host:port`) for the primary node; omitted when
            the primary is not yet RUNNING or does not expose SSH (22/tcp).
          examples:
            - 1.2.3.4:22001
    PersistentMount:
      type: object
      required:
        - size
        - path
      additionalProperties: false
      description: |
        Host-local persistent storage. Pinned to the pod's host machine — data
        does not survive a host failure. Disallowed on CPU pods. Mutually
        exclusive with NetworkMount. Deprecated: prefer NetworkMount for any
        data you cannot recreate.
      properties:
        size:
          type: integer
          minimum: 10
          description: >-
            Host-local persistent storage in GB. Upstream enforces a 10 GB
            floor.
          examples:
            - 20
        path:
          type: string
          description: Mount path inside the container. May be changed via PATCH.
          examples:
            - /workspace
    NetworkMount:
      type: object
      required:
        - volumeId
        - path
      additionalProperties: false
      description: |
        Reference to a NetworkVolume. Custom paths are honored at runtime on
        both GPU and CPU pods. The underlying `volumeId` is immutable
        post-create; the mount `path` may be changed via PATCH.
      properties:
        volumeId:
          type: string
          description: ID of an existing NetworkVolume in the same data center as the pod.
          examples:
            - vol_xyz
        path:
          type: string
          description: >-
            Mount path inside the container. No default — must be specified
            explicitly.
          examples:
            - /runpod-volume
    PodStatus:
      type: string
      description: |
        Lifecycle status of a pod.
        - `PROVISIONING` — pod is being allocated
        - `STARTING`     — container is starting
        - `RUNNING`      — container is healthy
        - `EXITED`       — container exited (stopped)
        - `ERROR`        — container is in an unrecoverable error state
        - `TERMINATED`   — pod has been permanently deleted
      enum:
        - PROVISIONING
        - STARTING
        - RUNNING
        - EXITED
        - ERROR
        - TERMINATED
    RateLimitHeader:
      type: string
      description: |
        Live per-window quota state. Optional — omitted for rate-limit-exempt
        callers.

        A structured-field list with one member per window (`minute`, `hour`,
        `day`), each carrying the remaining request count `r` and seconds until
        the window resets `t`. Returned on responses to authenticated requests,
        not only on 429s.
      examples:
        - '"minute";r=0;t=12, "hour";r=2800;t=1812, "day";r=49500;t=45012'
    RateLimitPolicyHeader:
      type: string
      description: >
        Static per-window quota policy. Optional — omitted for rate-limit-exempt

        callers.


        A structured-field list with one member per window (`minute`, `hour`,

        `day`), each carrying the quota `q` and the window length in seconds
        `w`.

        Returned on responses to authenticated requests, not only on 429s.
      examples:
        - '"minute";q=60;w=60, "hour";q=3000;w=3600, "day";q=50000;w=86400'
  responses:
    BadRequestError:
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimit-Policy'
      description: >-
        The request could not be processed because it is malformed or conflicts
        with request rules.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            badRequest:
              summary: Bad request
              value:
                title: Bad Request
                status: 400
                detail: request could not be processed
    UnauthorizedError:
      description: >-
        Authentication failed because the bearer token is missing, malformed,
        expired, or invalid.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missingBearerToken:
              summary: Missing bearer token
              value:
                title: Unauthorized
                status: 401
                detail: missing bearer token
    ForbiddenError:
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimit-Policy'
      description: >-
        The bearer token is valid, but it does not grant access to the requested
        resource or action.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            insufficientAccess:
              summary: Insufficient access
              value:
                title: Forbidden
                status: 403
                detail: access denied
    UnprocessableEntityError:
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimit-Policy'
      description: >-
        The request body or parameters were syntactically valid but failed
        validation.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            validationFailed:
              summary: Validation failed
              value:
                title: Unprocessable Entity
                status: 422
                detail: Request validation failed.
    TooManyRequestsError:
      description: >
        The caller exceeded its per-user rate limit. The response identifies the
        window that was exceeded and how long to wait. The `RateLimit` and
        `RateLimit-Policy` headers (per the IETF ratelimit-headers draft) also
        accompany successful responses, so clients can track quota before a 429.
      headers:
        Retry-After:
          description: Seconds to wait before retrying, per the exceeded window.
          schema:
            type: integer
          example: 12
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimit-Policy'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            rateLimited:
              summary: Rate limit exceeded
              value:
                title: Too Many Requests
                status: 429
                detail: rate limit exceeded for the minute window
  headers:
    RateLimit:
      schema:
        $ref: '#/components/schemas/RateLimitHeader'
    RateLimit-Policy:
      schema:
        $ref: '#/components/schemas/RateLimitPolicyHeader'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Runpod API Key
      description: >
        Runpod API key authentication. Generate an API key in the Runpod console
        and send it in the `Authorization` header as `Bearer <api_key>`. 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.

````