> ## 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.

# Mark a suggestion pulled

> Records that you applied a suggestion in code (`mb pull` does this after writing the candidate). No body (`{}` is accepted too; a body with any field is 400). proposed -> pulled; marking a pulled suggestion again is a no-op that returns it. Any other status is 409 with `details.status`, the status it has: a rejected, accepted or superseded suggestion can't be pulled. Once the candidate serves primary production traffic, it is recorded as `accepted`. Another environment's suggestion is 404.



## OpenAPI

````yaml /openapi.json post /v1/suggestions/{suggestion_id}/mark-pulled
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.


    **Lists.** A list answers one page: `{environment, items, next_cursor,
    has_more}` (named `<Thing>Page`), in the order the operation states. Pass
    `next_cursor` back as `cursor`, with the same filters, while `has_more` is
    true; on the last page `next_cursor` is null. `limit` defaults to 50 and is
    at most 100, with these exceptions: cases go up to 200 a page (a run's
    batch; 50 with content), suggestions default to 20, since each carries its
    whole candidate structure and evidence, and the review queue (a reviewer's
    screen) defaults to 20, at most 50.


    **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: []
tags:
  - name: Evaluate
    description: Run one item through a decision and read evaluations back. Start here.
  - name: Decisions
    description: >-
      Validate a decision file, register its versions, and read decisions and
      versions.
  - name: Feedback
    description: >-
      Say what the right answer was, import labeled examples, and read feedback
      and cases.
  - name: Suggestions
    description: Ask for a better version of a decision, and follow the improvement loop.
  - name: Previews & tests
    description: >-
      Replay a structure change over past cases, and score a version over many
      items.
  - name: Models
    description: List the models a decision can run on and choose one.
  - name: Objective
    description: >-
      Set what a decision optimizes for, then judge runs and tune cuts against
      it.
  - name: Usage
    description: What a decision's model calls cost.
  - name: Account
    description: Identify your key, and check that the API is up.
paths:
  /v1/suggestions/{suggestion_id}/mark-pulled:
    post:
      tags:
        - Suggestions
      summary: Mark a suggestion pulled
      description: >-
        Records that you applied a suggestion in code (`mb pull` does this after
        writing the candidate). No body (`{}` is accepted too; a body with any
        field is 400). proposed -> pulled; marking a pulled suggestion again is
        a no-op that returns it. Any other status is 409 with `details.status`,
        the status it has: a rejected, accepted or superseded suggestion can't
        be pulled. Once the candidate serves primary production traffic, it is
        recorded as `accepted`. Another environment's suggestion is 404.
      operationId: markSuggestionPulled
      parameters:
        - schema:
            $ref: '#/components/schemas/SuggestionId'
          required: true
          name: suggestion_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: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MarkSuggestionPulledRequest'
      responses:
        '200':
          description: The pulled suggestion
          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:
                pulled:
                  summary: >-
                    Applied in the repository and marked pulled; accepted once
                    it serves production traffic
                  value:
                    id: sug_0199f2c4-1a2b-7c3d-8e4f-5a6b7c8d9e70
                    decision_id: refund-exception
                    kind: new_question
                    target: structure
                    summary: >-
                      Ask whether the parcel arrived late or got lost, and count
                      it toward granting
                    environment: test
                    base:
                      version:
                        structure_hash: >-
                          sha256:bdad6e5b1b879209305f1555b43ec62666a4d74a925280c66e54cc4dc07bb1ae
                        number: 1
                      model:
                        profile: >-
                          defective=jev:jev-1.14.0@jev@0.1.0,item_used=jev:jev-1.14.0@jev@0.1.0
                    candidate:
                      version:
                        structure_hash: >-
                          sha256:8b4e793adb3c0d8dbf8b57fd9fe3450789681a5d0a727e0e2013514fc210506d
                        number: null
                      model:
                        profile: >-
                          defective=jev:jev-1.14.0@jev@0.1.0,item_used=jev:jev-1.14.0@jev@0.1.0,shipping_failure=jev:jev-1.14.0@jev@0.1.0
                    requires: []
                    candidate_structure:
                      questions:
                        item_used:
                          type: noul
                          instructions: >-
                            Has the customer used the item beyond trying it on
                            or setting it up once?
                          reads:
                            - state.message
                        defective:
                          type: noul
                          instructions: >-
                            Does the customer describe a defect, damage on
                            arrival, or the item failing under normal use?
                          reads:
                            - state.message
                        shipping_failure:
                          type: noul
                          instructions: >-
                            Did the order arrive later than promised, or get
                            lost in transit?
                          reads:
                            - state.message
                      attributes:
                        days_since_delivery:
                          type: number
                          minimum: 0
                      aggregations:
                        grant_score:
                          type: weighted_mean
                          inputs:
                            - name: questions.item_used
                              invert: true
                            - name: questions.defective
                            - name: questions.shipping_failure
                        handling:
                          type: rules
                          rules:
                            - when:
                                name: attributes.days_since_delivery
                                gt: 30
                              outcome: escalate
                            - when:
                                name: aggregations.grant_score
                                gte: 0.72
                              outcome: grant
                            - when:
                                name: aggregations.grant_score
                                lt: 0.38
                              outcome: deny
                          else: escalate
                      result: aggregations.handling
                    diff:
                      - op: add
                        path: /questions/shipping_failure
                        after:
                          type: noul
                          instructions: >-
                            Did the order arrive later than promised, or get
                            lost in transit?
                          reads:
                            - state.message
                      - op: add
                        path: /aggregations/grant_score/inputs/-
                        after:
                          name: questions.shipping_failure
                    evidence:
                      label: training_cases
                      frozen_at: '2026-11-06T16:00:00.000Z'
                      by_split:
                        train:
                          'n': 5
                          fixes: 2
                          breaks: 0
                          base_correct: 3
                          candidate_correct: 5
                      noise_rate: 0
                      action_mix: null
                      changed_items:
                        - evaluation_id: evl_0199f2c4-1a2b-7c3d-8e4f-5a6b7c8d9e41
                          feedback_id: fbk_0199f2c4-1a2b-7c3d-8e4f-5a6b7c8d9e50
                          split: train
                          change: fix
                          before:
                            outcome: escalate
                            answers:
                              item_used: 0.02
                              defective: 0.3
                          after:
                            outcome: grant
                            answers:
                              item_used: 0.02
                              defective: 0.3
                              shipping_failure: 0.97
                        - evaluation_id: evl_0199f2c4-1a2b-7c3d-8e4f-5a6b7c8d9e42
                          feedback_id: fbk_0199f2c4-1a2b-7c3d-8e4f-5a6b7c8d9e51
                          split: train
                          change: fix
                          before:
                            outcome: escalate
                            answers:
                              item_used: 0
                              defective: 0.2
                          after:
                            outcome: grant
                            answers:
                              item_used: 0
                              defective: 0.2
                              shipping_failure: 0.99
                      credited_feedback: []
                    preview_id: prv_0199f2c4-1a2b-7c3d-8e4f-5a6b7c8d9e71
                    objective:
                      revision: 1
                      objective_hash: >-
                        sha256:17c4fed8a47b7094ae83485aab46436ced0b00f24be5b059f2bf6984a4e4e4b3
                    generator:
                      name: anthropic
                      version: '3'
                      model: claude-sonnet
                    status: pulled
                    created_at: '2026-11-06T16:00:00.000Z'
                    status_at: '2026-11-06T17:00:00.000Z'
              schema:
                $ref: '#/components/schemas/Suggestion'
        '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'
        '409':
          description: Conflict with the current state
          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:
    SuggestionId:
      type: string
      pattern: >-
        ^sug_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
    MarkSuggestionPulledRequest:
      type: object
      properties: {}
      additionalProperties: false
      description: 'No fields: send no body, or `{}`.'
    Suggestion:
      type: object
      properties:
        id:
          $ref: '#/components/schemas/SuggestionIdOutput'
        decision_id:
          $ref: '#/components/schemas/DecisionIdOutput'
        kind:
          $ref: '#/components/schemas/SuggestionKind'
        target:
          $ref: '#/components/schemas/SuggestionTarget'
        summary:
          type: string
        environment:
          $ref: '#/components/schemas/Environment'
        base:
          $ref: '#/components/schemas/VersionRef'
        candidate:
          $ref: '#/components/schemas/VersionRef'
        requires:
          type: array
          items:
            $ref: '#/components/schemas/SuggestionIdOutput'
        candidate_structure:
          $ref: '#/components/schemas/DecisionStructureOutput'
        diff:
          type: array
          items:
            $ref: '#/components/schemas/StructureDiffEntry'
        evidence:
          $ref: '#/components/schemas/Evidence'
        preview_id:
          type: string
          pattern: >-
            ^(prv|run)_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
          description: >-
            The preview that is this suggestion's evidence: `prv_`, or `run_`
            for one stored before `prv_`.
        objective:
          anyOf:
            - $ref: '#/components/schemas/ObjectiveRef'
            - type: 'null'
          description: >-
            The stored objective revision its preview was scored with, or null
            when none was set (balanced losses). Absent on suggestions made
            before previews were judged, when none was set.
        generator:
          $ref: '#/components/schemas/Generator'
        status:
          $ref: '#/components/schemas/SuggestionStatusOutput'
        status_at:
          $ref: '#/components/schemas/TimestampOutput'
        rejection_reason:
          type: string
        accepted_evaluation_id:
          $ref: '#/components/schemas/EvaluationIdOutput'
        accepted_at:
          $ref: '#/components/schemas/TimestampOutput'
        created_at:
          $ref: '#/components/schemas/TimestampOutput'
        stale:
          type: object
          properties:
            reason:
              type: string
            cases:
              type: integer
              minimum: 1
              description: How many of its evaluated cases have changed feedback.
          required:
            - reason
            - cases
          additionalProperties: true
          description: >-
            Present when feedback on cases this suggestion was evaluated on
            changed after its evidence was read: an answer it read was changed,
            withdrawn or corrected, or the owner, a reviewer or an imported
            example judged one of its cases since, or any feedback since marked
            one's input as broken. Its evidence is as it was then; preview it
            again before relying on it.
          x-moonbounce-sdk-known-fields: true
      required:
        - id
        - decision_id
        - kind
        - target
        - summary
        - environment
        - base
        - candidate
        - requires
        - candidate_structure
        - diff
        - evidence
        - preview_id
        - generator
        - status
        - created_at
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    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
    SuggestionIdOutput:
      type: string
      pattern: >-
        ^sug_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
    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.
    SuggestionKind:
      type: string
      enum:
        - question_rewrite
        - new_question
      description: >-
        question_rewrite: new wording for one question (its question text and
        criteria). new_question: one new question, added as an input of the
        aggregation that feeds the result's bands or rules.
    SuggestionTarget:
      type: string
      enum:
        - structure
    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.
    VersionRef:
      type: object
      properties:
        version:
          $ref: '#/components/schemas/EvaluatedVersion'
        model:
          $ref: '#/components/schemas/ModelProfile'
      required:
        - version
        - model
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    DecisionStructureOutput:
      type: object
      properties:
        questions:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/QuestionOutput'
          description: System One questions, keyed by name.
        attributes:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/AttributeOutput'
          description: >-
            Values your app supplies with each call in `attribute_values`. The
            model never sees them.
        aggregations:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/AggregationOutput'
        result:
          type: string
          minLength: 1
          maxLength: 80
          description: The final feature's path, such as `aggregations.band`.
          examples:
            - questions.asks_for_refund
            - aggregations.band
      required:
        - questions
        - result
      additionalProperties: true
      description: >-
        Everything that defines a decision: questions, attribute declarations,
        aggregations and the result. Names are unique across all three maps.
      x-moonbounce-sdk-known-fields: true
    StructureDiffEntry:
      type: object
      properties:
        op:
          type: string
          enum:
            - replace
            - add
            - remove
        path:
          type: string
          pattern: ^\/(questions|aggregations)\/[a-z][a-z0-9_]*(\/[^/]*)*$
        before: {}
        after: {}
      required:
        - op
        - path
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    Evidence:
      type: object
      properties:
        label:
          $ref: '#/components/schemas/EvidenceLabel'
        frozen_at:
          $ref: '#/components/schemas/TimestampOutput'
        by_split:
          type: object
          properties:
            example:
              $ref: '#/components/schemas/SplitStats'
            train:
              $ref: '#/components/schemas/SplitStats'
          additionalProperties: true
          x-moonbounce-sdk-known-fields: true
        noise_rate:
          type:
            - number
            - 'null'
          minimum: 0
          maximum: 1
        by_source:
          type: object
          properties:
            app_native:
              $ref: '#/components/schemas/SplitStats'
            app_resolution:
              $ref: '#/components/schemas/SplitStats'
            reviewer:
              $ref: '#/components/schemas/SplitStats'
            owner:
              $ref: '#/components/schemas/SplitStats'
            import:
              $ref: '#/components/schemas/SplitStats'
            synthetic_review:
              $ref: '#/components/schemas/SplitStats'
        action_mix:
          anyOf:
            - $ref: '#/components/schemas/ActionMix'
            - type: 'null'
        changed_items:
          type: array
          items:
            $ref: '#/components/schemas/ChangedItem'
        credited_feedback:
          type: array
          items:
            $ref: '#/components/schemas/FeedbackIdOutput'
      required:
        - label
        - frozen_at
        - by_split
        - noise_rate
        - action_mix
        - changed_items
        - credited_feedback
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    ObjectiveRef:
      type: object
      properties:
        revision:
          type: integer
          minimum: 1
        objective_hash:
          type: string
      required:
        - revision
        - objective_hash
      additionalProperties: true
      description: The stored objective revision in effect, and its hash.
      x-moonbounce-sdk-known-fields: true
    Generator:
      type: object
      properties:
        name:
          type: string
          minLength: 1
        version:
          type: string
          minLength: 1
        model:
          type: string
      required:
        - name
        - version
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    SuggestionStatusOutput:
      type: string
      enum:
        - proposed
        - pulled
        - accepted
        - rejected
        - superseded
    TimestampOutput:
      type: string
      format: date-time
    EvaluationIdOutput:
      type: string
      pattern: >-
        ^evl_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
    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
    EvaluatedVersion:
      type: object
      properties:
        structure_hash:
          $ref: '#/components/schemas/StructureHashOutput'
        number:
          type:
            - integer
            - 'null'
          minimum: 1
          description: >-
            The version's number under the decision (1, 2, 3...). Null when the
            structure isn't registered: a dry run or a preview of a structure
            nobody registered. The hash is the identity.
      required:
        - structure_hash
        - number
      additionalProperties: true
      description: The version that ran.
      x-moonbounce-sdk-known-fields: true
    ModelProfile:
      type: object
      properties:
        profile:
          type: string
          description: >-
            Every question's model and connector, as one opaque string. Compare
            it for equality (two runs are comparable when their profiles match);
            don't parse it.
      required:
        - profile
      additionalProperties: true
      description: The model that answered, as its opaque profile.
      x-moonbounce-sdk-known-fields: true
    QuestionOutput:
      oneOf:
        - $ref: '#/components/schemas/NoulQuestionOutput'
      discriminator:
        propertyName: type
        mapping:
          noul: '#/components/schemas/NoulQuestionOutput'
    AttributeOutput:
      oneOf:
        - $ref: '#/components/schemas/StringAttributeOutput'
        - $ref: '#/components/schemas/NumberAttributeOutput'
        - $ref: '#/components/schemas/BooleanAttributeOutput'
      discriminator:
        propertyName: type
        mapping:
          string: '#/components/schemas/StringAttributeOutput'
          number: '#/components/schemas/NumberAttributeOutput'
          boolean: '#/components/schemas/BooleanAttributeOutput'
    AggregationOutput:
      oneOf:
        - $ref: '#/components/schemas/WeightedMeanOutput'
        - $ref: '#/components/schemas/LogisticOutput'
        - $ref: '#/components/schemas/MinOutput'
        - $ref: '#/components/schemas/MaxOutput'
        - $ref: '#/components/schemas/ProductOutput'
        - $ref: '#/components/schemas/NoisyOrOutput'
        - $ref: '#/components/schemas/AllOutput'
        - $ref: '#/components/schemas/AnyOutput'
        - $ref: '#/components/schemas/BandsOutput'
        - $ref: '#/components/schemas/RulesOutput'
        - $ref: '#/components/schemas/MatchOutput'
      discriminator:
        propertyName: type
        mapping:
          weighted_mean: '#/components/schemas/WeightedMeanOutput'
          logistic: '#/components/schemas/LogisticOutput'
          min: '#/components/schemas/MinOutput'
          max: '#/components/schemas/MaxOutput'
          product: '#/components/schemas/ProductOutput'
          noisy_or: '#/components/schemas/NoisyOrOutput'
          all: '#/components/schemas/AllOutput'
          any: '#/components/schemas/AnyOutput'
          bands: '#/components/schemas/BandsOutput'
          rules: '#/components/schemas/RulesOutput'
          match: '#/components/schemas/MatchOutput'
    EvidenceLabel:
      type: string
      enum:
        - imported_examples
        - training_cases
    SplitStats:
      type: object
      properties:
        'n':
          type: integer
          minimum: 0
        fixes:
          type: integer
          minimum: 0
        breaks:
          type: integer
          minimum: 0
        base_correct:
          type: integer
          minimum: 0
        candidate_correct:
          type: integer
          minimum: 0
      required:
        - 'n'
        - fixes
        - breaks
        - base_correct
        - candidate_correct
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    ActionMix:
      type: object
      properties:
        before:
          type: object
          additionalProperties:
            type: number
            minimum: 0
            maximum: 1
        after:
          type: object
          additionalProperties:
            type: number
            minimum: 0
            maximum: 1
        'on':
          type: string
        'n':
          type: integer
          minimum: 0
      required:
        - before
        - after
        - 'on'
        - 'n'
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    ChangedItem:
      type: object
      properties:
        evaluation_id:
          $ref: '#/components/schemas/EvaluationIdOutput'
        feedback_id:
          $ref: '#/components/schemas/FeedbackIdOutput'
        split:
          $ref: '#/components/schemas/Split'
        change:
          type: string
          enum:
            - fix
            - break
        before:
          type: object
          properties:
            outcome:
              $ref: '#/components/schemas/OutcomeOutput'
            value:
              type: number
            answers:
              type: object
              additionalProperties:
                type:
                  - number
                  - 'null'
                minimum: 0
                maximum: 1
          required:
            - answers
          additionalProperties: true
          x-moonbounce-sdk-known-fields: true
        after:
          type: object
          properties:
            outcome:
              $ref: '#/components/schemas/OutcomeOutput'
            value:
              type: number
            answers:
              type: object
              additionalProperties:
                type:
                  - number
                  - 'null'
                minimum: 0
                maximum: 1
          required:
            - answers
          additionalProperties: true
          x-moonbounce-sdk-known-fields: true
      required:
        - evaluation_id
        - feedback_id
        - split
        - change
        - before
        - after
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    FeedbackIdOutput:
      type: string
      pattern: >-
        ^fbk_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
    StructureHashOutput:
      type: string
      pattern: ^sha256:[0-9a-f]{64}$
    NoulQuestionOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - noul
        instructions:
          $ref: '#/components/schemas/InstructionsOutput'
        criteria:
          type: object
          properties:
            'true':
              type: string
              minLength: 1
              maxLength: 4000
            'false':
              type: string
              minLength: 1
              maxLength: 4000
          additionalProperties: true
          x-moonbounce-sdk-known-fields: true
        reads:
          type: array
          items:
            $ref: '#/components/schemas/StatePathOutput'
          minItems: 1
          maxItems: 64
          description: >-
            Paths into an object `state` this question reads, such as
            `state.message` or `state.order.customer.tier`. The question sees
            just those values, nested as in the state. Without it the question
            sees the whole state, as in System One. Every path must exist in the
            call's `state`; no entry may repeat or contain another.
      required:
        - type
        - instructions
      additionalProperties: true
      description: P(true) for a statement about the state.
      x-moonbounce-sdk-known-fields: true
    StringAttributeOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - string
        enum:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 200
          minItems: 1
          maxItems: 255
        default:
          type: string
        source:
          type: string
          minLength: 1
          maxLength: 200
          description: >-
            The model and version behind this attribute, such as
            `toxicity-classifier-v3`. Hashed.
        from:
          type: string
          minLength: 1
          maxLength: 256
          description: >-
            A state path (as in `reads`) evaluate fills this attribute from, in
            place of `attribute_values`: the value at that path, validated by
            this declaration with no coercion. A missing or null path takes
            `default`, else it is a 400. A value for it in `attribute_values` is
            a 400. Hashed as written.
          examples:
            - state.message
            - state.order.order_total_usd
      required:
        - type
        - enum
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    NumberAttributeOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - number
        minimum:
          type: number
        maximum:
          type: number
        default:
          type: number
        source:
          type: string
          minLength: 1
          maxLength: 200
          description: >-
            The model and version behind this attribute, such as
            `toxicity-classifier-v3`. Hashed.
        from:
          type: string
          minLength: 1
          maxLength: 256
          description: >-
            A state path (as in `reads`) evaluate fills this attribute from, in
            place of `attribute_values`: the value at that path, validated by
            this declaration with no coercion. A missing or null path takes
            `default`, else it is a 400. A value for it in `attribute_values` is
            a 400. Hashed as written.
          examples:
            - state.message
            - state.order.order_total_usd
      required:
        - type
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    BooleanAttributeOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - boolean
        default:
          type: boolean
        source:
          type: string
          minLength: 1
          maxLength: 200
          description: >-
            The model and version behind this attribute, such as
            `toxicity-classifier-v3`. Hashed.
        from:
          type: string
          minLength: 1
          maxLength: 256
          description: >-
            A state path (as in `reads`) evaluate fills this attribute from, in
            place of `attribute_values`: the value at that path, validated by
            this declaration with no coercion. A missing or null path takes
            `default`, else it is a 400. A value for it in `attribute_values` is
            a 400. Hashed as written.
          examples:
            - state.message
            - state.order.order_total_usd
      required:
        - type
      additionalProperties: true
      x-moonbounce-sdk-known-fields: true
    WeightedMeanOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - weighted_mean
        inputs:
          type: array
          items:
            type: object
            properties:
              name:
                $ref: '#/components/schemas/FeatureRefOutput'
              weight:
                type: number
                exclusiveMinimum: 0
              invert:
                type: boolean
            required:
              - name
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 64
      required:
        - type
        - inputs
      additionalProperties: true
      description: 'Σ wᵢ·xᵢ / Σ wᵢ: a weighted average from 0 to 1, not a probability.'
      x-moonbounce-sdk-known-fields: true
    LogisticOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - logistic
        bias:
          type: number
        inputs:
          type: array
          items:
            type: object
            properties:
              name:
                $ref: '#/components/schemas/FeatureRefOutput'
              weight:
                type: number
            required:
              - name
              - weight
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 64
      required:
        - type
        - bias
        - inputs
      additionalProperties: true
      description: σ(bias + Σ wᵢ·xᵢ), with signed weights on raw input values.
      x-moonbounce-sdk-known-fields: true
    MinOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - min
        inputs:
          type: array
          items:
            type: object
            properties:
              name:
                $ref: '#/components/schemas/FeatureRefOutput'
              invert:
                type: boolean
            required:
              - name
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 64
      required:
        - type
        - inputs
      additionalProperties: true
      description: 'min xᵢ: all of these, when they overlap.'
      x-moonbounce-sdk-known-fields: true
    MaxOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - max
        inputs:
          type: array
          items:
            type: object
            properties:
              name:
                $ref: '#/components/schemas/FeatureRefOutput'
              invert:
                type: boolean
            required:
              - name
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 64
      required:
        - type
        - inputs
      additionalProperties: true
      description: 'max xᵢ: any of these, when they overlap.'
      x-moonbounce-sdk-known-fields: true
    ProductOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - product
        inputs:
          type: array
          items:
            type: object
            properties:
              name:
                $ref: '#/components/schemas/FeatureRefOutput'
              invert:
                type: boolean
            required:
              - name
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 64
      required:
        - type
        - inputs
      additionalProperties: true
      description: 'Π xᵢ: all of these, when they are independent.'
      x-moonbounce-sdk-known-fields: true
    NoisyOrOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - noisy_or
        inputs:
          type: array
          items:
            type: object
            properties:
              name:
                $ref: '#/components/schemas/FeatureRefOutput'
              invert:
                type: boolean
            required:
              - name
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 64
      required:
        - type
        - inputs
      additionalProperties: true
      description: '1 − Π(1 − xᵢ): any of these, when they are independent.'
      x-moonbounce-sdk-known-fields: true
    AllOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - all
        inputs:
          type: array
          items:
            type: object
            properties:
              name:
                $ref: '#/components/schemas/FeatureRefOutput'
              gte:
                type: number
              gt:
                type: number
              lte:
                type: number
              lt:
                type: number
            required:
              - name
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 64
      required:
        - type
        - inputs
      additionalProperties: true
      description: 1 when every input passes its threshold (default ≥ 0.5), else 0.
      x-moonbounce-sdk-known-fields: true
    AnyOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - any
        inputs:
          type: array
          items:
            type: object
            properties:
              name:
                $ref: '#/components/schemas/FeatureRefOutput'
              gte:
                type: number
              gt:
                type: number
              lte:
                type: number
              lt:
                type: number
            required:
              - name
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 64
      required:
        - type
        - inputs
      additionalProperties: true
      description: 1 when any input passes its threshold (default ≥ 0.5), else 0.
      x-moonbounce-sdk-known-fields: true
    BandsOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - bands
        input:
          $ref: '#/components/schemas/FeatureRefOutput'
        below:
          $ref: '#/components/schemas/NameOutput'
        cuts:
          type: array
          items:
            type: object
            properties:
              at:
                type: number
              outcome:
                $ref: '#/components/schemas/NameOutput'
            required:
              - at
              - outcome
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 9
        abstain:
          $ref: '#/components/schemas/NameOutput'
      required:
        - type
        - input
        - below
        - cuts
      additionalProperties: true
      description: >-
        Names an outcome for each range of one feature's value. `at` means ≥;
        `below` is under the first cut.
      x-moonbounce-sdk-known-fields: true
    RulesOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - rules
        rules:
          type: array
          items:
            type: object
            properties:
              when:
                $ref: '#/components/schemas/ConditionOutput'
              outcome:
                $ref: '#/components/schemas/NameOutput'
            required:
              - when
              - outcome
            additionalProperties: true
            x-moonbounce-sdk-known-fields: true
          minItems: 1
          maxItems: 64
        else:
          $ref: '#/components/schemas/NameOutput'
      required:
        - type
        - rules
        - else
      additionalProperties: true
      description: >-
        The first rule whose condition is true names its `outcome`; otherwise
        `else`.
      x-moonbounce-sdk-known-fields: true
    MatchOutput:
      type: object
      properties:
        type:
          type: string
          enum:
            - match
        input:
          $ref: '#/components/schemas/FeatureRefOutput'
        cases:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/NameOutput'
          description: >-
            Maps labels to outcomes. "__proto__" is not supported as a case key;
            use a rules is-condition for that label.
        else:
          $ref: '#/components/schemas/NameOutput'
        abstain:
          $ref: '#/components/schemas/NameOutput'
      required:
        - type
        - input
        - cases
      additionalProperties: true
      description: Maps a label straight to an outcome.
      x-moonbounce-sdk-known-fields: true
    Split:
      type: string
      enum:
        - example
        - train
    OutcomeOutput:
      type: string
      minLength: 1
      maxLength: 200
      description: >-
        An outcome name, or the exact enum label when a string attribute is the
        result.
    InstructionsOutput:
      anyOf:
        - type: string
          minLength: 1
          maxLength: 4000
        - type: object
          additionalProperties: {}
        - type: array
          items: {}
          minItems: 1
    StatePathOutput:
      type: string
      minLength: 1
      maxLength: 256
      description: >-
        `state.<key>` or a nested object path such as
        `state.order.customer.tier`: keys of an object `state`. A key has no
        `.`, `[` or `]`. Array indexes are not supported yet.
      examples:
        - state.message
        - state.order.order_total_usd
    FeatureRefOutput:
      type: string
      minLength: 1
      maxLength: 80
      description: >-
        A feature's path: `questions.<name>`, `attributes.<name>` or
        `aggregations.<name>`.
      examples:
        - questions.asks_for_refund
        - aggregations.band
    NameOutput:
      type: string
      pattern: ^[a-z][a-z0-9_]{0,63}$
    ConditionOutput:
      anyOf:
        - type: object
          properties:
            name:
              $ref: '#/components/schemas/FeatureRefOutput'
            gte:
              type: number
            gt:
              type: number
            lte:
              type: number
            lt:
              type: number
            is:
              type: string
              minLength: 1
              maxLength: 200
            in:
              type: array
              items:
                type: string
                minLength: 1
                maxLength: 200
              minItems: 1
              maxItems: 255
            abstained:
              type: boolean
              enum:
                - true
          required:
            - name
          additionalProperties: true
          x-moonbounce-sdk-known-fields: true
        - type: object
          properties:
            all:
              type: array
              items:
                $ref: '#/components/schemas/ConditionOutput'
              minItems: 1
              maxItems: 64
          required:
            - all
          additionalProperties: true
          x-moonbounce-sdk-known-fields: true
        - type: object
          properties:
            any:
              type: array
              items:
                $ref: '#/components/schemas/ConditionOutput'
              minItems: 1
              maxItems: 64
          required:
            - any
          additionalProperties: true
          x-moonbounce-sdk-known-fields: true
        - type: object
          properties:
            not:
              $ref: '#/components/schemas/ConditionOutput'
          required:
            - not
          additionalProperties: true
          x-moonbounce-sdk-known-fields: true
  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.