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

> ## Agent Instructions
> If this page is missing information, contains outdated instructions, or doesn't fully answer the user's question, use the feedback tool to report it. In your feedback, be specific about what's missing, what appears out of date, or what needs to be corrected or updated, so the docs team can act on it directly.

> Create a multi-node Runpod Cluster with a consistent compute shape and container configuration across every member Pod.

# Create a cluster



## 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:
            compute:
              $ref: '#/components/schemas/ClusterCompute'
            name:
              type: string
              minLength: 1
              examples:
                - my-training-cluster
            type:
              $ref: '#/components/schemas/ClusterType'
            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
            mounts:
              $ref: '#/components/schemas/Mounts'
            startJupyter:
              type: boolean
              default: false
              description: Start Jupyter on every member pod, as on pod create.
            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.
      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:
        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
        env:
          type: object
          additionalProperties:
            type: string
          description: Environment variables as key-value pairs
          examples:
            - JUPYTER_PASSWORD: hunter2
        image:
          type: string
          description: Docker image reference
          examples:
            - runpod/pytorch:1.0.2-cu1281-torch280-ubuntu2404
        ports:
          type: array
          description: Exposed ports, formatted as port/protocol
          items:
            type: string
          examples:
            - - 8888/http
              - 22/tcp
    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
    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
    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.

````