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

# Update a stack

> Save changes to a stack as a new revision.

Updates a stack owned by the manager identified by your API key.
Every accepted update creates a new complete revision.

<Note>
  Try it saves a real update to staging. Every accepted update creates a
  revision. Use a stack ID from your own account.
</Note>

Omitted fields retain their values from the current saved revision.
A supplied `allocation` replaces the **entire** target list.
Omitting a token from that supplied list removes its allocation.
The replacement still needs weights totaling `10000`.

An empty object is invalid.
Unknown fields and `null` field values are invalid.

## Response

`200 OK` returns the complete [stack response](/api-reference/stack-configuration#stack-response) with the new `current_revision_id`.
The response includes the new quoted revision ID in `ETag`.
It also includes `X-Request-Id`.

The saved configuration is visible immediately.
An update does not trigger an immediate trade.
See [schedules](/api-reference/stack-configuration#schedules) for preset meanings and the planned execution contract.

## Revisions and concurrent updates

Every successfully saved update creates a revision.
This includes an update that repeats the current values.

Concurrent updates are saved in sequence.
For each supplied field, the last successfully saved value wins.
A delayed older request can overwrite a newer request that was saved first.
Omitted fields are copied from the current configuration when the update is saved.

Neither `If-Match` nor `Idempotency-Key` is required or enforced for this endpoint.
Sending them does not protect against overwrites or deduplicate a retry.

<Warning>
  A retried PATCH is a new update. If a response is lost, read the stack before
  deciding whether to send another update. Use one ordered stream of updates per
  stack when your client needs to preserve its intended order.
</Warning>

## Errors

| Status | Code              | Cause                                                                      |
| ------ | ----------------- | -------------------------------------------------------------------------- |
| `400`  | `invalid_request` | Invalid stack UUID, malformed JSON, empty patch, or invalid configuration. |
| `404`  | `not_found`       | Stack is missing or belongs to another manager.                            |

See [shared errors](/api-reference/errors) for authentication, body size, and service failures.


## OpenAPI

````yaml PATCH /manager/stacks/{id}
openapi: 3.1.0
info:
  title: MyStacks Manager API
  version: 1.0.0
  description: >-
    Create, read, and update your stacks. MyStacks generates API keys and
    supplies them to wealth managers. Authenticate with the supplied key in the
    Authorization header using the Bearer scheme. Your key identifies your
    manager account. Every response includes X-Request-Id. The API saves
    configuration. Automated scheduled trading is still being built.
servers:
  - url: https://api-staging.mystacks.ai
    description: MyStacks staging backend
security:
  - ManagerApiKey: []
tags:
  - name: Stacks
    description: Manage your stack configurations and current revisions.
paths:
  /manager/stacks/{id}:
    parameters:
      - $ref: '#/components/parameters/StackId'
      - $ref: '#/components/parameters/RequestId'
    patch:
      tags:
        - Stacks
      summary: Update a stack
      description: >-
        Append a complete configuration revision with at least one supplied
        field. Omitted fields are copied from the current revision while the
        stack row is locked. A supplied allocation replaces the entire target
        list. Every valid committed update creates a revision, including updates
        that repeat current values. This operation is not idempotent. It
        requires neither Idempotency-Key nor If-Match. Concurrent updates
        serialize. The last committed value for each supplied field wins. A
        delayed request or retry can overwrite a value saved by another request.
        Read the stack after an uncertain result before retrying. The saved
        configuration is visible immediately. Existing operations retain their
        chosen revision. Saving configuration does not execute trades.
      operationId: updateStack
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateStackRequest'
            example:
              name: Updated example stack
              schedule:
                preset: weekly
      responses:
        '200':
          description: Complete saved configuration with the new revision and ETag.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ManagerStack'
              example:
                id: bf4bc5e9-0d9e-454c-bc1c-30abc120b074
                current_revision_id: e137435f-83ce-4b3c-86ae-75d6462487b6
                name: Updated example stack
                allocation:
                  - token_address: '0x117cc2133c37b721f49de2a7a74833232b3b4c0c'
                    weight_bps: 6000
                  - token_address: '0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec'
                    weight_bps: 4000
                schedule:
                  preset: weekly
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  parameters:
    StackId:
      name: id
      in: path
      required: true
      description: >-
        UUID of a stack owned by this manager. Missing or unowned stacks return
        404. Invalid UUIDs return 400.
      schema:
        type: string
        format: uuid
      example: bf4bc5e9-0d9e-454c-bc1c-30abc120b074
    RequestId:
      name: X-Request-Id
      in: header
      required: false
      description: >-
        Optional request trace ID. A nonempty value is echoed in the response.
        Missing or empty values cause a UUID to be generated.
      schema:
        type: string
  schemas:
    UpdateStackRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          $ref: '#/components/schemas/StackName'
        allocation:
          $ref: '#/components/schemas/Allocation'
        schedule:
          $ref: '#/components/schemas/Schedule'
      required: []
      minProperties: 1
      description: >-
        Supply at least one of name, allocation, or schedule. Omitted fields
        retain their saved values. A supplied allocation replaces the full
        target list. Unknown fields and null values are invalid. The request
        body must not exceed 262144 bytes.
      example:
        name: Updated example stack
        schedule:
          preset: weekly
    ManagerStack:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
          description: Stable stack identifier.
          example: bf4bc5e9-0d9e-454c-bc1c-30abc120b074
        current_revision_id:
          type: string
          format: uuid
          description: Identifier of this complete saved configuration revision.
          example: e137435f-83ce-4b3c-86ae-75d6462487b6
        name:
          $ref: '#/components/schemas/StackName'
        allocation:
          $ref: '#/components/schemas/NormalizedAllocation'
        schedule:
          $ref: '#/components/schemas/Schedule'
      required:
        - id
        - current_revision_id
        - name
        - allocation
        - schedule
      description: >-
        Current complete configuration. No subscriber, balance, performance, or
        execution data is included.
      example:
        id: bf4bc5e9-0d9e-454c-bc1c-30abc120b074
        current_revision_id: e137435f-83ce-4b3c-86ae-75d6462487b6
        name: Example stack
        allocation:
          - token_address: '0x117cc2133c37b721f49de2a7a74833232b3b4c0c'
            weight_bps: 6000
          - token_address: '0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec'
            weight_bps: 4000
        schedule:
          preset: daily
    StackName:
      type: string
      minLength: 1
      pattern: ^(?![\s\S]*\u0000)[\s\S]*\S[\s\S]*$
      description: >-
        Must contain non-whitespace text and must not contain U+0000. Accepted
        names retain their exact whitespace. No separate name-length limit
        applies within the body size limit.
      example: Example stack
    Allocation:
      type: array
      minItems: 1
      maxItems: 30
      items:
        $ref: '#/components/schemas/AllocationItem'
      description: >-
        The complete target allocation. Weights must total exactly 10000.
        Duplicate token identities are rejected after lowercase normalization.
        When supplied in PATCH, this list replaces the full saved allocation.
        Omitted tokens are removed.
      example:
        - token_address: '0x117cc2133c37b721f49de2a7a74833232b3b4c0c'
          weight_bps: 6000
        - token_address: '0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec'
          weight_bps: 4000
    Schedule:
      type: object
      additionalProperties: false
      properties:
        preset:
          type: string
          enum:
            - hourly
            - daily
            - weekly
            - monthly
          description: >-
            Saved UTC schedule preset. Planned boundaries are minute zero each
            hour, 00:00 each day, 00:00 each Monday, or 00:00 on the first day
            of each month. Custom schedules and timezone fields are invalid.
            Automated scheduled trading is still being built.
          example: daily
      required:
        - preset
      description: Schedule configuration only. Saving a preset does not execute trades.
      example:
        preset: daily
    NormalizedAllocation:
      type: array
      minItems: 1
      maxItems: 30
      items:
        $ref: '#/components/schemas/NormalizedAllocationItem'
      description: >-
        Complete saved allocation. Addresses are lowercase, unique, and ordered
        by token address. Weights total exactly 10000.
      example:
        - token_address: '0x117cc2133c37b721f49de2a7a74833232b3b4c0c'
          weight_bps: 6000
        - token_address: '0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec'
          weight_bps: 4000
    Error:
      type: object
      additionalProperties: false
      properties:
        code:
          type: string
          enum:
            - invalid_request
            - unauthorized
            - not_found
            - conflict
            - payload_too_large
            - rate_limited
            - internal_error
            - service_unavailable
          description: Machine-readable error category.
          example: invalid_request
        message:
          type: string
          description: >-
            Public-safe explanation. No field-by-field validation details are
            returned.
          example: invalid request body
        request_id:
          type: string
          description: >-
            Matches the response X-Request-Id header. This can be a
            caller-supplied string, not only a UUID.
          example: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
      required:
        - code
        - message
        - request_id
      example:
        code: invalid_request
        message: invalid request body
        request_id: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
    AllocationItem:
      type: object
      additionalProperties: false
      properties:
        token_address:
          $ref: '#/components/schemas/TokenAddress'
        weight_bps:
          $ref: '#/components/schemas/WeightBps'
      required:
        - token_address
        - weight_bps
      example:
        token_address: '0x117cc2133c37b721f49de2a7a74833232b3b4c0c'
        weight_bps: 6000
    NormalizedAllocationItem:
      type: object
      additionalProperties: false
      properties:
        token_address:
          $ref: '#/components/schemas/NormalizedTokenAddress'
        weight_bps:
          $ref: '#/components/schemas/WeightBps'
      required:
        - token_address
        - weight_bps
      example:
        token_address: '0x117cc2133c37b721f49de2a7a74833232b3b4c0c'
        weight_bps: 6000
    TokenAddress:
      type: string
      pattern: ^0x[0-9a-fA-F]{40}$
      description: >-
        A token from the 30-asset Robinhood Chain mainnet whitelist (chain ID
        4663). Use a lowercase or correctly checksummed address. The pattern
        checks address syntax only. The server also enforces checksum validity
        and whitelist membership before normalizing identity to lowercase. USDG
        is not an allocation token. See [supported
        assets](/api-reference/assets) for all accepted addresses.
      example: '0x117cc2133c37b721f49de2a7a74833232b3b4c0c'
    WeightBps:
      type: integer
      minimum: 0
      maximum: 10000
      description: >-
        Target weight in basis points. 10000 means 100%. Zero is allowed. All
        allocation weights together must total exactly 10000.
      example: 6000
    NormalizedTokenAddress:
      type: string
      pattern: ^0x[0-9a-f]{40}$
      enum:
        - '0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec'
        - '0x117cc2133c37b721f49de2a7a74833232b3b4c0c'
        - '0x4a0e65a3eccec6dbe60ae065f2e7bb85fae35eea'
        - '0xccee82fe024c36fa15e1005ede3e9e4787e23d09'
        - '0x05b37fb53a299a1b874a619e1c4c404d52c36f4c'
        - '0xff080c8ce2e5feadaca0da81314ae59d232d4afd'
        - '0xa30fa36db767ad9ed3f7a60fc79526fb4d56d344'
        - '0xec262a75e413fafd0df80480274532c79d42da09'
        - '0xd5f3879160bc7c32ebb4dc785f8a4f505888de68'
        - '0x1b0e319c6a659f002271b69db8a7df2f911c153e'
        - '0x12f190a9f9d7d37a250758b26824b97ce941bf54'
        - '0xaf3d76f1834a1d425780943c99ea8a608f8a93f9'
        - '0x58ffe4a942d3885baa22d7520691f611ef09e7aa'
        - '0x86923f96303d656e4aa86d9d42d1e57ad2023fdc'
        - '0x2e0847e8910a9732eb3fb1bb4b70a580adad4fe3'
        - '0x4ea005168d7f09a7a0ba9d1def21a479950e44c2'
        - '0xe93237c50d904957cf27e7b1133b510c669c2e74'
        - '0x322f0929c4625ed5bad873c95208d54e1c003b2d'
        - '0xc0d6457c16cc70d6790dd43521c899c87ce02f35'
        - '0x9e7abd3c9139d14e4c86dce0e455aab7a0c2fb3e'
        - '0xb90a19ff0af67f7779aff50a882a9cff42446400'
        - '0xc72b96e0e48ecd4dc75e1e45396e26300bc39681'
        - '0x894e1ec2d74ffe5aef8dc8a9e84686accb964f2a'
        - '0x1d11f0496982706c5e14a514d4e79f2e6bde4516'
        - '0x411efb0e7f985935daec3d4c3ebaea0d0ad7d89f'
        - '0x5e81213613b6b86eab4c6c50d718d34359459786'
        - '0xc9a981fee1f9dec688bb123ccdecc63d0debfc4e'
        - '0x6330d8c3178a418788df01a47479c0ce7ccf450b'
        - '0xdf0992e440dd0be65bd8439b609d6d4366bf1cb5'
        - '0x48e39e56acdba37b09020c0b734a613c9a2f100a'
      description: >-
        A supported trading token address normalized to lowercase. See
        [supported assets](/api-reference/assets) for names and symbols.
      example: '0x117cc2133c37b721f49de2a7a74833232b3b4c0c'
  headers:
    RequestId:
      description: >-
        Request trace ID. A nonempty incoming X-Request-Id is reused. If missing
        or empty, the server generates a UUID. Error request_id values match
        this header.
      schema:
        type: string
      example: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
    ETag:
      description: >-
        Current revision ID enclosed in double quotes. PATCH does not require
        If-Match and does not enforce conditional updates.
      schema:
        type: string
        pattern: ^"[0-9a-fA-F-]{36}"$
      example: '"e137435f-83ce-4b3c-86ae-75d6462487b6"'
  responses:
    BadRequest:
      description: Invalid JSON, configuration, pagination, stack UUID, or creation key.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: invalid_request
            message: invalid request body
            request_id: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
    Unauthorized:
      description: >-
        Missing or invalid manager credential, or verified identity lacks
        required identity fields or a canonical lowercase UUID external ID.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: unauthorized
            message: invalid manager credential
            request_id: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
    NotFound:
      description: The stack does not exist or belongs to another manager.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: not_found
            message: stack not found
            request_id: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
    PayloadTooLarge:
      description: Request body exceeds 262144 bytes.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: payload_too_large
            message: request body exceeds 262144 bytes
            request_id: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
    RateLimited:
      description: >-
        API-key verification was rate limited. No fixed quota or Retry-After
        header contract is published.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: rate_limited
            message: manager verification rate limited
            request_id: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
    InternalError:
      description: >-
        Unexpected internal failure or conflicting saved manager identity
        binding.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: internal_error
            message: an unexpected error occurred
            request_id: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
    ServiceUnavailable:
      description: >-
        API-key verification timed out or is unavailable. No access is granted
        and no stack changes occur.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: service_unavailable
            message: manager verification is unavailable
            request_id: d28e1ad4-2ca8-4f35-b590-8bf3b53abc81
  securitySchemes:
    ManagerApiKey:
      type: http
      scheme: bearer
      description: >-
        Enter the API key supplied by MyStacks. The playground adds the
        `Authorization: Bearer` prefix for you.

````