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

# Set a Sailbox's limits

> Set this Sailbox's vCPU count, memory limit, or disk limit. Regardless of configured limits, you are only charged for the resources the Sailbox workload actually consumes at runtime. Limits are for finer grained control over a Sailbox's allowable resource consumption, and most users keep the defaults of 8 vCPUs, a 256 GiB memory limit, and a 1024 GiB disk limit. Every field is optional, but at least one must be set; a field left out keeps its value.

A running Sailbox takes the change in place: memory moves both ways (a lowering stops one GiB above what is in use, and the response's `memory_mib` is the limit that took effect), disk only grows, and a vCPU change brings CPUs online or takes them offline. A paused or sleeping Sailbox is not woken: the new limits are recorded, take effect at its next wake, and the response has `applied: false`.

The full rules, including what is refused and why, are in the [set limits guide](https://docs.sailresearch.com/sailbox-sdk#set_limits).



## OpenAPI

````yaml /sailbox-openapi.json post /sailboxes/{sailbox_id}/set-limits
openapi: 3.1.0
info:
  title: Sail Sailbox API
  version: '2026-10-04'
  description: >-
    Create and operate Sailboxes over HTTP. Sailboxes are fast-booting virtual
    machines that you can pause, resume, and checkpoint.


    Run commands, stream files, manage lifecycle and networking, and inspect
    usage. Turning on SSH and building an image still require an SDK or the CLI.
    See the [HTTP API guide](/sailboxes-http-api).
servers:
  - url: https://sailbox-api.sailresearch.com/v1
security:
  - BearerAuth: []
tags:
  - name: Apps
    description: Groups that own Sailboxes. One app per workload.
  - name: Lifecycle
    description: >-
      A Sailbox's whole life: create it, watch it, stop and start it, terminate
      it.
  - name: Checkpoints
    description: Save a Sailbox to start from later, and copy a running one.
  - name: Exec
    description: Run commands and control their standard input and terminals.
  - name: Files
    description: Stream regular files into and out of a Sailbox.
  - name: Networking
    description: >-
      Publish ports, serve them on hostnames you own, and identify a Sailbox to
      other Sailboxes.
  - name: Secrets
    description: >-
      Organization values that egress policy rules can add to matching requests.
      Sail never returns a stored value.
  - name: Egress policies
    description: >-
      What a Sailbox may connect to, and what happens to the HTTPS requests it
      sends.
  - name: Volumes
    description: >-
      Shared storage that outlives any one Sailbox. Alpha: these endpoints can
      still change.
  - name: SSH access
    description: Certificates for connecting to a Sailbox with `ssh`.
  - name: Usage
    description: Resource usage and spend.
  - name: Identity
    description: Who your API key belongs to.
paths:
  /sailboxes/{sailbox_id}/set-limits:
    post:
      tags:
        - Lifecycle
      summary: Set a Sailbox's limits
      description: >-
        Set this Sailbox's vCPU count, memory limit, or disk limit. Regardless
        of configured limits, you are only charged for the resources the Sailbox
        workload actually consumes at runtime. Limits are for finer grained
        control over a Sailbox's allowable resource consumption, and most users
        keep the defaults of 8 vCPUs, a 256 GiB memory limit, and a 1024 GiB
        disk limit. Every field is optional, but at least one must be set; a
        field left out keeps its value.


        A running Sailbox takes the change in place: memory moves both ways (a
        lowering stops one GiB above what is in use, and the response's
        `memory_mib` is the limit that took effect), disk only grows, and a vCPU
        change brings CPUs online or takes them offline. A paused or sleeping
        Sailbox is not woken: the new limits are recorded, take effect at its
        next wake, and the response has `applied: false`.


        The full rules, including what is refused and why, are in the [set
        limits guide](https://docs.sailresearch.com/sailbox-sdk#set_limits).
      operationId: setSailboxLimits
      parameters:
        - $ref: '#/components/parameters/SailboxId'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/OwnerOverrideReason'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetSailboxLimitsRequest'
            example:
              vcpu_count: 8
              memory_limit_gib: 48
      responses:
        '200':
          description: The Sailbox's limits after the call.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SailboxLimitsResult'
          headers:
            Idempotent-Replayed:
              $ref: '#/components/headers/IdempotentReplayed'
        '400':
          description: >-
            A limit is outside the range the vCPU count allows, `vcpu_count` is
            outside 1 to 8, the disk limit is below the current one, a field is
            0 or empty, the body sets no field, or the body is not valid JSON.
            See the error message.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: memory_limit_gib 4 is below the 16 GiB minimum for 8 vCPUs
                  type: invalid_request_error
                  param: memory_limit_gib
                  code: invalid_argument
          headers:
            Idempotent-Replayed:
              $ref: '#/components/headers/IdempotentReplayed'
        '401':
          description: The API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: Invalid API key
                  type: authentication_error
                  param: null
                  code: invalid_api_key
        '402':
          description: >-
            The organization is out of credits. The error carries a
            `billing_url` pointing at the page where you add them. Retry once
            you have.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: >-
                    Your API key has been disabled due to insufficient credits.
                    Visit https://app.sailresearch.com/billing to add credits.
                  type: billing_error
                  param: null
                  code: credits_exhausted
                  billing_url: https://app.sailresearch.com/billing
        '403':
          description: The API key is not allowed to perform this operation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: sailboxes require an organization-scoped API key
                  type: permission_error
                  param: null
                  code: null
          headers:
            Idempotent-Replayed:
              $ref: '#/components/headers/IdempotentReplayed'
        '404':
          description: No Sailbox with that id exists in your organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: sailbox "sb_9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d" not found
                  type: not_found_error
                  param: null
                  code: null
          headers:
            Idempotent-Replayed:
              $ref: '#/components/headers/IdempotentReplayed'
        '409':
          description: >-
            The change cannot apply in the Sailbox's current state: the memory
            limit would be lowered on a powered-off Sailbox, the Sailbox uses
            more memory than the requested shape allows, the Sailbox is in a
            state that allows no changes, or the `Idempotency-Key` was reused
            for a different request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: >-
                    lower the memory limit while the Sailbox is running; Sail
                    cannot see what a sleeping Sailbox is using
                  type: conflict_error
                  param: null
                  code: failed_precondition
          headers:
            Idempotent-Replayed:
              $ref: '#/components/headers/IdempotentReplayed'
        '413':
          description: The request body is larger than the 64 KiB this endpoint accepts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: request body too large
                  type: invalid_request_error
                  param: null
                  code: null
        '429':
          description: >-
            Too many requests in flight, or the organization is at a limit. A
            `Retry-After` header means the request never started, so retry it
            unchanged after that delay. Without one, the request ran and hit the
            limit `message` names. Some of those clear on their own, such as a
            shortage of public ports; others need you to free something up
            first. Send the request again once the cause is gone.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: >-
                    Too many concurrent requests. Please retry after some of
                    your organization's in-flight requests complete.
                  type: rate_limit_error
                  param: null
                  code: rate_limited
          headers:
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
        '500':
          description: Server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: failed to fetch sailbox
                  type: server_error
                  param: null
                  code: null
        '503':
          description: >-
            Sail is momentarily unavailable. Retry after the delay in the
            `Retry-After` header when one is present, and with backoff
            otherwise.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: Authentication service unavailable
                  type: server_error
                  param: null
                  code: null
          headers:
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
        '504':
          description: >-
            The operation outran its deadline, or a retry sent with the same
            `Idempotency-Key` waited about 30 seconds and the original request
            was still going. Retry with the same key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: idempotent request still in flight
                  type: server_error
                  param: null
                  code: null
components:
  parameters:
    SailboxId:
      name: sailbox_id
      in: path
      required: true
      schema:
        type: string
      description: >-
        Id of the Sailbox, as returned by create. It is `sb_` followed by a
        UUID.
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        maxLength: 255
      description: >-
        Makes the request retry-safe. Sail remembers the answer it sent under a
        key, including a 400 or a 409, and replays it with `Idempotent-Replayed:
        true` for a retry that repeats the key, the method, the path, and the
        body. Bodies are compared byte for byte. Reusing a key for a different
        request returns 409, so send a corrected request under a new key. A key
        that is blank or only spaces is ignored, and the request runs without
        idempotency.


        Any string of up to 255 bytes works, and characters outside ASCII count
        for more than one. A UUID is a good default. Keys are remembered for at
        least 24 hours and scoped to the API key that sent them.


        A server error, or a failure to record the answer, can leave a key
        unsettled, and creating a Sailbox is where that matters. See [Retrying
        safely](/sailboxes-http-api#retrying-safely).
    OwnerOverrideReason:
      name: X-Sail-Owner-Override-Reason
      in: header
      required: false
      schema:
        type: string
        pattern: ^[ -~]*$
      description: >-
        Lets an organization admin operate a `private` Sailbox someone else
        created. Say why in plain text; the reason goes into your organization's
        audit log, and the operation is refused without it. Ignored on Sailboxes
        you could already operate.


        Pause, resume, sleep, scheduled wake, upgrade, reboot, set limits, and
        terminate accept an override, and so does deleting a checkpoint taken
        from the Sailbox. Setting an egress policy accepts one too. Running
        commands and moving files accept one through an SDK or the CLI.
        Publishing and unpublishing ports, adding and removing custom domains,
        checkpointing, and creating from a checkpoint stay with the creator.
  schemas:
    SetSailboxLimitsRequest:
      type: object
      description: >-
        The limits to set on a Sailbox: its vCPU count, memory limit, and disk
        limit. Regardless of configured limits, you are only charged for the
        resources the Sailbox workload actually consumes at runtime. Limits are
        for finer grained control over a Sailbox's allowable resource
        consumption. Every field is optional, but at least one must be set. A
        field left out (or null) keeps its current value, and a value equal to
        the current one is accepted and changes nothing. A field set to 0 or to
        an empty string is rejected.
      properties:
        vcpu_count:
          type: integer
          minimum: 1
          maximum: 8
          description: >-
            The new vCPU count, 1 to 8. A memory limit below the new count's
            minimum is raised to it.
        size:
          type: string
          enum:
            - s
            - m
            - l
          deprecated: true
          description: >-
            Deprecated; set `vcpu_count` instead. Stands for the vCPU count of
            the retired size: `s` is 1, `m` is 4, `l` is 8. Sizes will be
            unsupported in future SDK versions.
        memory_limit_gib:
          type: integer
          minimum: 1
          description: >-
            The new memory limit in whole GiB, within the range for the
            Sailbox's vCPU count after the call: 2 to 256 with 1 vCPU, 8 to 256
            with 2 to 4, and 16 to 256 with 5 to 8. Lowering it needs a running
            Sailbox. The limit cannot come within a GiB of what the Sailbox is
            using: it settles one GiB above that amount, rounded up to a whole
            GiB, when that is higher; the response reports the limit that took
            effect.
        state_disk_limit_gib:
          type: integer
          minimum: 1
          description: >-
            The new disk limit in GiB, 8 to 1024. A disk only grows: a value
            below the current limit is refused.
    SailboxLimitsResult:
      type: object
      properties:
        sailbox_id:
          type: string
          description: Id of the Sailbox.
        status:
          type: string
          description: >-
            Current state of the Sailbox. Values in use today are `creating`,
            `running`, `paused`, `sleeping`, `terminating`, `terminated`,
            `failed`, `create_failed`, `interrupted_restorable`, and
            `interrupted_unsafe_to_retry`. New values can appear over time, so
            treat this as an open set.
        applied:
          type: boolean
          description: >-
            `true` when the Sailbox has the new limits now. `false` when it was
            powered off: the limits are recorded and take effect at the next
            wake. Also `false` when a restart the change needed could not
            complete; the Sailbox is then paused with the new limits recorded.
        restarted:
          type: boolean
          description: >-
            `true` when the change restarted the Sailbox. Files on its disk were
            kept; running processes and memory were not.
        size:
          type: string
          deprecated: true
          description: >-
            Deprecated; read `vcpu_count` instead. The retired size label whose
            vCPU count matches the Sailbox now: `s` for 1, `m` for 4, `l` for 8.
            Empty for any other count.
        vcpu_count:
          type: integer
          description: Virtual CPUs the Sailbox has now.
        memory_mib:
          type: integer
          description: >-
            The memory limit in MiB that took effect. On a lowering this can be
            above what you asked for, because the limit lands one GiB above what
            the Sailbox is using.
        state_disk_size_gib:
          type: integer
          description: The disk limit in GiB now.
        memory_in_use_mib:
          oneOf:
            - type: integer
            - type: 'null'
          description: >-
            Memory the Sailbox was using when its memory limit was lowered while
            running, in MiB; the lowered limit lands one GiB above it. `null`
            for any other change.
      required:
        - sailbox_id
        - status
        - applied
        - restarted
        - size
        - vcpu_count
        - memory_mib
        - state_disk_size_gib
        - memory_in_use_mib
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorObject'
    ErrorObject:
      type: object
      required:
        - message
        - type
        - param
        - code
      properties:
        message:
          type: string
          description: Human-readable description of what went wrong.
        type:
          type: string
          description: >-
            Error category: `invalid_request_error`, `authentication_error`,
            `permission_error`, `billing_error`, `not_found_error`,
            `conflict_error`, `rate_limit_error`, `quota_exceeded_error`,
            `not_implemented_error`, or `server_error`.
        param:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            The request field the error refers to, when the error is about one
            field.
        code:
          oneOf:
            - type: string
            - type: integer
            - type: 'null'
          description: >-
            Stable short code for the error, when one applies. Errors relayed
            from the Sailbox runtime carry its status token, for example
            `already_exists` or `failed_precondition` on a 409, which the HTTP
            status alone does not distinguish.
        billing_url:
          type: string
          format: uri
          description: Page where you add credits. Sent with a 402.
      additionalProperties: true
  headers:
    IdempotentReplayed:
      description: >-
        `true` when this response is the stored answer to an earlier request
        that sent the same `Idempotency-Key`. Absent when the request ran for
        the first time.
      schema:
        type: string
        enum:
          - 'true'
    RetryAfter:
      description: >-
        How many seconds to wait before retrying. On a 429 it also means the
        request never started, so the retry can reuse the same
        `Idempotency-Key`.
      schema:
        type: integer
        minimum: 0
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key

````