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

# Engine and model cost for a decision, per evaluation and in total

> Engine cost of one decision's evaluations and previews over a window; reads only. What the decision's evaluations cost over a window, for the key's organization and environment. Amounts are US dollars in micros (`usd_micros`: millionths of a dollar). Costs are what our engines reported, priced by each adapter from the vendor's published price, plus an estimate for calls we couldn't price from a vendor report (no usage reported, or a suggestion-writer model with no listed price), broken out as `estimated_usd_micros`; cache hits cost nothing. Evaluations that never committed and suggestion generation (its replays and model call) are in `other_spend`, outside the per-evaluation numbers, and `total` adds everything recorded. Per-request `cost` on evaluate and seeds is reported cost only. `since` (inclusive) and `until` (exclusive) are read to the millisecond and default to the last 30 days ending now; the window may span at most 366 days. A decision with no traffic in the window answers 200 with empty groups. The web session may not read it (403).



## OpenAPI

````yaml /openapi.json get /v1/decisions/{decision_id}/usage
openapi: 3.1.0
info:
  title: Moonbounce Decisions API
  version: 0.0.0
  description: >-
    Moonbounce decisions: evaluate items against a decision spec (features
    combined by aggregators), record feedback and seed examples, review a ranked
    queue, and improve the spec 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/specs/hash`. 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/specs/hash`). 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, counted per Cloudflare location.
servers:
  - url: https://api.moonbounce.ai
    description: Production
security: []
paths:
  /v1/decisions/{decision_id}/usage:
    get:
      tags:
        - usage
      summary: Engine and model cost for a decision, per evaluation and in total
      description: >-
        Engine cost of one decision's evaluations and previews over a window;
        reads only. What the decision's evaluations cost over a window, for the
        key's organization and environment. Amounts are US dollars in micros
        (`usd_micros`: millionths of a dollar). Costs are what our engines
        reported, priced by each adapter from the vendor's published price, plus
        an estimate for calls we couldn't price from a vendor report (no usage
        reported, or a suggestion-writer model with no listed price), broken out
        as `estimated_usd_micros`; cache hits cost nothing. Evaluations that
        never committed and suggestion generation (its replays and model call)
        are in `other_spend`, outside the per-evaluation numbers, and `total`
        adds everything recorded. Per-request `cost` on evaluate and seeds is
        reported cost only. `since` (inclusive) and `until` (exclusive) are read
        to the millisecond and default to the last 30 days ending now; the
        window may span at most 366 days. A decision with no traffic in the
        window answers 200 with empty groups. The web session may not read it
        (403).
      operationId: getUsage
      parameters:
        - schema:
            $ref: '#/components/schemas/DecisionId'
          required: true
          name: decision_id
          in: path
        - schema:
            type: string
            format: date-time
            description: 'Start of the window, inclusive. Default: `until` - 30 days.'
          required: false
          description: 'Start of the window, inclusive. Default: `until` - 30 days.'
          name: since
          in: query
        - schema:
            type: string
            format: date-time
            description: 'End of the window, exclusive. Default: now.'
          required: false
          description: 'End of the window, exclusive. Default: now.'
          name: until
          in: query
      responses:
        '200':
          description: The decision's cost report
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecisionUsage'
        '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'
        '429':
          description: >-
            RATE_LIMITED: retry after Retry-After seconds; QUOTA_EXCEEDED:
            details.reset_at gives the daily reset time (no Retry-After), or
            details.too_large asks for a smaller request
          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: []
components:
  schemas:
    DecisionId:
      type: string
      pattern: ^[a-z][a-z0-9_.-]{0,127}$
    DecisionUsage:
      type: object
      properties:
        decision_id:
          $ref: '#/components/schemas/DecisionId'
        environment:
          $ref: '#/components/schemas/Environment'
        window:
          type: object
          properties:
            since:
              type: string
              format: date-time
            until:
              type: string
              format: date-time
          required:
            - since
            - until
        evaluations:
          type: array
          items:
            type: object
            properties:
              engine_profile:
                type: string
              assignment_mode:
                type: string
              evaluations:
                type: integer
                minimum: 0
              uncached:
                type: integer
                minimum: 0
                description: >-
                  Evaluations that called an engine, answered or not; the rest
                  were answered from the feature cache.
              engine_calls:
                type: integer
                minimum: 0
                description: >-
                  Upstream calls made, including ones answered with an error and
                  ones abandoned at the deadline; `engines[]` counts every
                  attempt.
              input_tokens:
                type: integer
                minimum: 0
              output_tokens:
                type: integer
                minimum: 0
              usd_micros:
                type: object
                properties:
                  total:
                    type: number
                    minimum: 0
                  mean:
                    type: number
                    minimum: 0
                  p50:
                    type: number
                    minimum: 0
                  p95:
                    type: number
                    minimum: 0
                required:
                  - total
                  - mean
                  - p50
                  - p95
                description: >-
                  Per evaluation, in millionths of a US dollar: reported cost
                  plus the estimate for its calls that reported no usage.
              estimated_usd_micros:
                type: number
                minimum: 0
                description: >-
                  The estimated part of `usd_micros.total`: calls that may have
                  been billed but reported no usage.
            required:
              - engine_profile
              - assignment_mode
              - evaluations
              - uncached
              - engine_calls
              - input_tokens
              - output_tokens
              - usd_micros
              - estimated_usd_micros
          description: >-
            One group per engine profile and assignment mode, ordered by both.
            Spend whose evaluation is gone is grouped under `unknown`, as is
            dry-run spend, which has no evaluation.
        engines:
          type: array
          items:
            type: object
            properties:
              engine:
                type: string
              resolved_model:
                type: string
              adapter:
                type: string
              calls:
                type: integer
                minimum: 0
                description: Call attempts, retries and failures included.
              failed:
                type: integer
                minimum: 0
                description: Attempts whose status is not `ok`.
              input_tokens:
                type: integer
                minimum: 0
              output_tokens:
                type: integer
                minimum: 0
              usd_micros:
                type: number
                minimum: 0
                description: Reported plus estimated.
              estimated_usd_micros:
                type: number
                minimum: 0
                description: >-
                  The estimated part: calls that may have been billed but
                  reported no usage.
            required:
              - engine
              - resolved_model
              - adapter
              - calls
              - failed
              - input_tokens
              - output_tokens
              - usd_micros
              - estimated_usd_micros
          description: >-
            One group per engine, resolved model and adapter, from the per-call
            traces. Evaluations stored before traces existed and dry runs
            contribute none.
        other_spend:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
                description: >-
                  `uncommitted`: evaluations, dry runs, seed examples and
                  preview runs whose engines ran but which never committed (a
                  failed evaluate, a refused seed batch, the loser of an
                  idempotency race, a preview that failed). `generation`:
                  suggestion generation's own replays and model call (its
                  proposal preview is in `previews`). New kinds may appear.
              attempts:
                type: integer
                minimum: 0
              engine_calls:
                type: integer
                minimum: 0
              input_tokens:
                type: integer
                minimum: 0
              output_tokens:
                type: integer
                minimum: 0
              model_input_tokens:
                type: integer
                minimum: 0
                description: >-
                  The suggestion writer's language model tokens, apart from
                  engine tokens.
              model_output_tokens:
                type: integer
                minimum: 0
              usd_micros:
                type: number
                minimum: 0
                description: Reported plus estimated.
              estimated_usd_micros:
                type: number
                minimum: 0
            required:
              - kind
              - attempts
              - engine_calls
              - input_tokens
              - output_tokens
              - model_input_tokens
              - model_output_tokens
              - usd_micros
              - estimated_usd_micros
          description: >-
            Spend that is not an evaluation, one group per kind, kept out of the
            per-evaluation numbers.
        total:
          type: object
          properties:
            usd_micros:
              type: number
              minimum: 0
            estimated_usd_micros:
              type: number
              minimum: 0
          required:
            - usd_micros
            - estimated_usd_micros
          description: 'Everything recorded above: evaluations, other spend and previews.'
        previews:
          type: object
          properties:
            runs:
              type: integer
              minimum: 0
            features_run:
              type: integer
              minimum: 0
              description: >-
                Feature answers the runs computed (not cached); one engine call
                can answer several.
            input_tokens:
              type: integer
              minimum: 0
            usd_micros:
              type: number
              minimum: 0
              description: Reported plus estimated.
            estimated_usd_micros:
              type: number
              minimum: 0
          required:
            - runs
            - features_run
            - input_tokens
            - usd_micros
            - estimated_usd_micros
          description: >-
            Stored preview runs in the window (`mb test`, previews, and the one
            preview each generated suggestion runs), which write no evaluations.
            Generation's exploratory replays and model call are in
            `other_spend`, as is a preview run that stored nothing
            (`uncommitted`).
      required:
        - decision_id
        - environment
        - window
        - evaluations
        - engines
        - other_spend
        - total
        - previews
    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 (`subject.0.text`,
                `claims.1.value`).
            details:
              type: object
              additionalProperties: {}
          required:
            - type
            - message
          additionalProperties: false
      required:
        - error
      additionalProperties: false
    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; registered structures are shared.
    ErrorType:
      type: string
      enum:
        - invalid_request
        - authentication
        - permission_denied
        - not_found
        - conflict
        - rate_limited
        - engine_failed
        - unavailable
        - internal
  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.