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

# Choose the model a decision runs on

> Sets the model a decision runs on in the calling key's environment, for every question, as a new revision of the setting. Evaluations run on it from the next call, and a switch also moves imported examples, previews and suggestions. The weights and cut points in a structure were set against one model's answers and are not checked against another's, so switch with a test key first and backtest there: each environment has its own setting. Always 200: `changed` is false, and no revision is written, when the body matches the current revision. A model this deployment does not offer is 400 CAPABILITY_UNSUPPORTED. 404 DECISION_UNKNOWN when the decision doesn't exist. An Idempotency-Key covers the body as sent, so retry with the same body; it replays even if the model's configuration changed.



## OpenAPI

````yaml /openapi.json put /v1/decisions/{decision_id}/model
openapi: 3.1.0
info:
  title: Moonbounce Decisions API
  version: 0.0.0
  description: >-
    Moonbounce decisions: evaluate an item's state against a decision structure
    (System One questions, attributes you supply and aggregations over both),
    record feedback and import labeled examples, review a ranked queue, and
    improve the structure through suggestions that ship as code diffs, each with
    a preview (backtest) and an evidence label.


    **Authentication.** Send an API key as `Authorization: Bearer <key>` on
    every operation except `GET /health` and `POST /v1/validate`. Call the API
    from a server, never a browser: a key must not reach one, and the API sends
    no CORS headers. A key belongs to one organization and one environment:
    production, or test for a key with the `env:test` permission. Test traffic
    never counts as production traffic.


    **Requests.** JSON bodies (`Content-Type: application/json`) of at most 1
    MB, parsed strictly: duplicate keys, lone surrogates, integers outside
    ±(2^53 - 1), `__proto__` keys, U+0000 and nesting deeper than 64 are a 400.


    **Retries.** Send an `Idempotency-Key` on every POST under /v1 that takes
    one (all but `POST /v1/validate` and `POST /v1/review/items/fill`, whose
    retry is another fill within the day's budget). Keep it for the request's
    retries. The same key with the same request returns the first stored result,
    marked `Idempotent-Replayed: true`, for 24 hours (410 if that result was
    since deleted); with another request it is 422 IDEMPOTENCY_KEY_REUSED. Keys
    are scoped to the organization and environment across every operation, so
    use a fresh key per request. A request that failed before its result was
    stored runs again when retried. 429 and 503 under /v1 may carry
    `Retry-After` (seconds); a daily QUOTA_EXCEEDED cap instead names its reset
    time.


    **Errors.** Every error under /v1 is `{"error": {"type", "message",
    "reason"?, "param"?, "details"?}}` (ErrorBody); `GET /health` answers its
    own shape. Every response carries a `Request-Id` header. Rate limits apply
    per key, and per client IP for requests without a valid key; a 429
    RATE_LIMITED carries `Retry-After`.
servers:
  - url: https://api.moonbounce.ai
    description: Production
security: []
paths:
  /v1/decisions/{decision_id}/model:
    put:
      tags:
        - models
      summary: Choose the model a decision runs on
      description: >-
        Sets the model a decision runs on in the calling key's environment, for
        every question, as a new revision of the setting. Evaluations run on it
        from the next call, and a switch also moves imported examples, previews
        and suggestions. The weights and cut points in a structure were set
        against one model's answers and are not checked against another's, so
        switch with a test key first and backtest there: each environment has
        its own setting. Always 200: `changed` is false, and no revision is
        written, when the body matches the current revision. A model this
        deployment does not offer is 400 CAPABILITY_UNSUPPORTED. 404
        DECISION_UNKNOWN when the decision doesn't exist. An Idempotency-Key
        covers the body as sent, so retry with the same body; it replays even if
        the model's configuration changed.
      operationId: setModel
      parameters:
        - schema:
            $ref: '#/components/schemas/DecisionId'
          required: true
          description: >-
            A name you choose for this decision, such as `refund-exception`: a
            lowercase letter, then up to 127 of `a-z 0-9 _ . -`. Unique in your
            organization and shared by its test and production keys. The first
            registration or evaluation under a new one creates the decision.
          name: decision_id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            pattern: ^[\x20-\x7e]+$
            description: >-
              Makes a retry safe. For 24 hours, the same key with the same
              request returns the first stored result (with Idempotent-Replayed:
              true); the same key with a different request is a 422
              IDEMPOTENCY_KEY_REUSED. Keys are scoped to the organization and
              environment across every operation, so use a fresh key per
              request. A request that failed before its result was stored runs
              again when retried with its key.
          required: false
          description: >-
            Makes a retry safe. For 24 hours, the same key with the same request
            returns the first stored result (with Idempotent-Replayed: true);
            the same key with a different request is a 422
            IDEMPOTENCY_KEY_REUSED. Keys are scoped to the organization and
            environment across every operation, so use a fresh key per request.
            A request that failed before its result was stored runs again when
            retried with its key.
          name: idempotency-key
          in: header
      requestBody:
        required: true
        content:
          application/json:
            examples:
              clef:
                summary: Move the decision to Clef in the key's environment
                value:
                  model: '@cf/cloudflare/clef'
            schema:
              $ref: '#/components/schemas/ModelSettingWrite'
      responses:
        '200':
          description: The setting, changed or not
          headers:
            Idempotent-Replayed:
              schema:
                type: string
                enum:
                  - 'true'
                description: >-
                  Present and `true` when this is the stored result of an
                  earlier request with the same Idempotency-Key.
              required: false
              description: >-
                Present and `true` when this is the stored result of an earlier
                request with the same Idempotency-Key.
          content:
            application/json:
              examples:
                changed:
                  summary: A new revision
                  value:
                    decision_id: refund-exception
                    environment: test
                    model: '@cf/cloudflare/clef'
                    pinned: false
                    revision: 2
                    source: setting
                    created_at: '2026-11-06T16:00:00.000Z'
                    changed: true
              schema:
                $ref: '#/components/schemas/ModelSettingWritten'
        '400':
          description: 'Invalid request: `param` names the field at fault when one applies'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
        '401':
          description: Missing or invalid API key (reason KEY_INVALID)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
        '403':
          description: The key may not do this
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
        '404':
          description: Not found, or not in this key's organization and environment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
        '410':
          description: >-
            The Idempotency-Key's first result was deleted, so it cannot be
            replayed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
        '413':
          description: The HTTP body exceeds 1 MB (reason BODY_TOO_LARGE)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
        '422':
          description: >-
            The request is well formed but cannot be processed
            (IDEMPOTENCY_KEY_REUSED requires a fresh key; REQUEST_TOO_LARGE
            requires a smaller request)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
        '429':
          description: >-
            RATE_LIMITED: retry after Retry-After seconds; QUOTA_EXCEEDED:
            details.reset_at gives the daily reset time (no Retry-After)
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying, when waiting helps.
              required: false
              description: Seconds to wait before retrying, when waiting helps.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
        '503':
          description: >-
            Temporarily unavailable, with Retry-After (for example reason
            AUTH_UNAVAILABLE, ENGINE_UNAVAILABLE or STORE_UNAVAILABLE): retry
            with the same Idempotency-Key
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying, when waiting helps.
              required: true
              description: Seconds to wait before retrying, when waiting helps.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
      security:
        - bearerAuth:
            - decisions:develop
components:
  schemas:
    DecisionId:
      type: string
      pattern: ^[a-z][a-z0-9_.-]{0,127}$
      description: >-
        A name you choose for this decision, such as `refund-exception`: a
        lowercase letter, then up to 127 of `a-z 0-9 _ . -`. Unique in your
        organization and shared by its test and production keys. The first
        registration or evaluation under a new one creates the decision.
    ModelSettingWrite:
      type: object
      properties:
        model:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            A model id from `GET /v1/models`, such as `jev-1.14.0`. `*-latest`
            and `*-preview` aliases are refused; whether an id fixes the model's
            behavior is its `pinned` flag. Open: new models are added without a
            contract change.
          example: jev-1.14.0
      required:
        - model
      additionalProperties: false
    ModelSettingWritten:
      allOf:
        - $ref: '#/components/schemas/ModelSetting'
        - type: object
          properties:
            changed:
              type: boolean
              description: >-
                False when the body matched the current revision, so nothing was
                written.
          required:
            - changed
    ErrorBody:
      type: object
      properties:
        error:
          type: object
          properties:
            type:
              $ref: '#/components/schemas/ErrorType'
            reason:
              type: string
              pattern: ^[A-Z][A-Z0-9_]+$
              description: >-
                Set where a caller can act on it, one of the reasons in the
                ErrorReason schema. New reasons may be added: treat an unknown
                one by the status and `type`.
            message:
              type: string
              description: For people; don't parse it.
            param:
              type: string
              description: >-
                The request field at fault, as a dotted path
                (`attribute_values.region`, `claims.1.value`).
            details:
              type: object
              properties:
                issues:
                  type: array
                  items:
                    $ref: '#/components/schemas/ErrorIssue'
              additionalProperties: {}
          required:
            - type
            - message
          additionalProperties: true
          x-moonbounce-sdk-known-fields: true
      required:
        - error
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    ModelSetting:
      type: object
      properties:
        decision_id:
          $ref: '#/components/schemas/DecisionIdOutput'
        environment:
          $ref: '#/components/schemas/Environment'
        model:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            A model id from `GET /v1/models`, such as `jev-1.14.0`. `*-latest`
            and `*-preview` aliases are refused; whether an id fixes the model's
            behavior is its `pinned` flag. Open: new models are added without a
            contract change.
          example: jev-1.14.0
        pinned:
          type: boolean
          description: >-
            Whether the model is pinned (see `GET /v1/models`). False when this
            deployment doesn't offer it.
        revision:
          type:
            - integer
            - 'null'
          minimum: 1
          description: >-
            Which edit of the setting this is: 1 for the first stored here, then
            2, 3... Evaluations report the one they ran on as `model.revision`.
            Null when nothing is stored in this environment and the deployment
            default applies.
        source:
          type: string
          enum:
            - setting
            - default
          description: >-
            `setting`: a stored revision. `default`: none is stored here, so the
            deployment default applies.
        created_at:
          type:
            - string
            - 'null'
          format: date-time
          description: When the revision was stored.
      required:
        - decision_id
        - environment
        - model
        - pinned
        - revision
        - source
        - created_at
    ErrorType:
      type: string
      enum:
        - invalid_request
        - authentication
        - permission_denied
        - not_found
        - conflict
        - rate_limited
        - engine_failed
        - unavailable
        - internal
    ErrorIssue:
      type: object
      properties:
        param:
          type: string
        code:
          type: string
          pattern: ^[A-Z][A-Z0-9_]+$
          description: >-
            Stable, extensible issue code; unknown codes still have a parameter
            and human-readable message.
        message:
          type: string
      required:
        - param
        - code
        - message
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    DecisionIdOutput:
      type: string
      pattern: ^[a-z][a-z0-9_.-]{0,127}$
      description: >-
        A name you choose for this decision, such as `refund-exception`: a
        lowercase letter, then up to 127 of `a-z 0-9 _ . -`. Unique in your
        organization and shared by its test and production keys. The first
        registration or evaluation under a new one creates the decision.
    Environment:
      type: string
      enum:
        - production
        - test
      description: >-
        The environment of the key that made the call: `production` or `test`.
        Evaluations, feedback, reviews and suggestions are separate per
        environment; decisions and their versions belong to the whole
        organization.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        An API key, sent as `Authorization: Bearer <key>`. Each operation lists
        the scope its key needs: `decisions:evaluate` (evaluate and read
        evaluations), `decisions:feedback` (your app's feedback) or
        `decisions:develop` (everything else, including owner feedback and the
        review queue). An operation listing no scope takes any scoped key. A key
        with no scope, or without the operation's, gets 403 INSUFFICIENT_SCOPE.

````

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