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

# Suggest sub-questions for a composite judgment

> Asks a general-purpose LLM for `count` narrow yes/no sub-questions
(§6.5.1). It is given the judgment's `question` and `criteria` (of
the newest version), and up to 30 of the namespace's labelled examples
for the judgment, balanced between `true` and `false` and compiled
with the judgment's context recipe. It returns the proposed parts and
the example documents it used. It never creates a version: review and
edit the parts, then create one.

- **Opt-in.** Refused with `forbidden` until an org admin enables
  `suggestions` in the org settings, because the examples go to an
  LLM provider, a disclosed subprocessor (§8).
- **Labels.** Needs at least 10 labelled examples of each answer
  (`insufficient_labels`). Labelled examples are outcomes (§6.10).
- **Limits.** Free, and limited to 20 calls per judgment and 50 per
  organization a day, with at most 100,000 tokens of examples per call
  (`rate_limited`, with `details.limit`, the limit reached: 20 for the
  judgment's or 50 for the organization's, and `details.resets_at`,
  the next midnight UTC, and no `Retry-After`). A call that fails with
  `engine_unavailable` before the model ran (it was overloaded or
  unreachable) does not count toward either; one that timed out or
  failed after the model replied does.




## OpenAPI

````yaml /api-reference/openapi.yaml post /namespaces/{ns}/judgments/{name}/suggest_parts
openapi: 3.1.0
info:
  title: Vainona API
  version: '1'
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
  description: |
    The `/v1` contract from main spec §6. It is locked: changes within `/v1`
    are additive only, and anything breaking is `/v2`.

    - **Base URL.** `https://api.vainona.ai/v1`.
    - **Evolution.** Response objects may gain fields and enums may gain values.
      Clients must ignore what they do not know. Request objects reject unknown
      fields.
    - **Path segments.** Namespace names (`{ns}`) and document ids (`{id}`) may
      contain `/`. Send it percent-encoded as `%2F`, so that
      `acme/prod/tenant_123` is `acme%2Fprod%2Ftenant_123`.
    - **Templates (v1.5).** The judgment routes also take a namespace prefix
      ending in `/*`, such as `acme%2Fprod%2F*`. A judgment created there is a
      template: every namespace under the prefix inherits it, including ones
      created later. The most specific matching prefix wins (§7.7).
    - **Thresholds are settings (v1.5).** Named thresholds belong to the
      judgment, not to a version. They are evaluated at read time against the
      raw fields, so a change applies at once to every answer, with no
      recompute and no new version (§6.5).
    - **Entity judgments (entities, E1).** A judgment can read the documents
      that point at the judged one, through `context.related`, and apply only
      to documents matching `applies_to` (§6.5.2). Its answers carry a
      `watermark`, and creating one that runs `on_change` returns a replay
      estimate of its monthly cost until you confirm (§6.9).
    - **Referenced documents (entities, E3a).** A relation can also read the
      one document the judged document points at, through
      `join: {theirs: "id", mine: "attributes.<name>"}`. A change to what the
      relation renders of that document re-judges the judged documents that
      point at it and are inside `freshness.fanout.scope`: a fan-out. A large
      fan-out is a `fanout` job that waits for confirm (§6.5.2, §6.9).
    - **Idempotency.** Every write operation is idempotent by construction.
      `Idempotency-Key` is accepted on every mutating route and, while the node
      still caches the original response, returns it verbatim.
    - **Errors.** Every error is the `Error` envelope; the HTTP status follows
      the code (see each response).
    - **Rate limits.** Every response carries `X-RateLimit-Limit` and
      `X-RateLimit-Remaining`; a `rate_limited` response adds `Retry-After`,
      except a daily allowance that is used up, which says when it renews in
      `details.resets_at` instead.
    - **Usage.** Every response that bills carries `usage`. Judging is billed in
      engine-neutral judgment units: one judgment answered, per started 1,000
      tokens of its compiled context and its question together, at least 1
      (§9). No response ever carries an
      engine's price.
servers:
  - url: https://api.vainona.ai/v1
security:
  - apiKey: []
tags:
  - name: Namespaces
    description: Namespaces, their settings and cache warming (§6.2, §6.11).
  - name: Documents
    description: Writes, point reads and queries (§6.3 to §6.8).
  - name: Judgments
    description: >-
      Judgment definitions, versions, settings, activation, backfill and
      template detach (§6.5, §6.9, §7.7).
  - name: Outcomes and calibration
    description: |
      Post what actually happened to judged documents, and read how well answers
      match it: the calibration report, calibrated answers and threshold
      recommendations (§6.10). See [calibration](/concepts/calibration).
  - name: Jobs
    description: >-
      Backfill, shadow, periodic, deletion, reference index and fan-out jobs
      (§6.2, §6.9, §7.10.5).
  - name: Engines
    description: The engine registry (§6.5, §7.4.5).
paths:
  /namespaces/{ns}/judgments/{name}/suggest_parts:
    parameters:
      - $ref: '#/components/parameters/Namespace'
      - $ref: '#/components/parameters/JudgmentName'
    post:
      tags:
        - Judgments
      summary: Suggest sub-questions for a composite judgment
      description: |
        Asks a general-purpose LLM for `count` narrow yes/no sub-questions
        (§6.5.1). It is given the judgment's `question` and `criteria` (of
        the newest version), and up to 30 of the namespace's labelled examples
        for the judgment, balanced between `true` and `false` and compiled
        with the judgment's context recipe. It returns the proposed parts and
        the example documents it used. It never creates a version: review and
        edit the parts, then create one.

        - **Opt-in.** Refused with `forbidden` until an org admin enables
          `suggestions` in the org settings, because the examples go to an
          LLM provider, a disclosed subprocessor (§8).
        - **Labels.** Needs at least 10 labelled examples of each answer
          (`insufficient_labels`). Labelled examples are outcomes (§6.10).
        - **Limits.** Free, and limited to 20 calls per judgment and 50 per
          organization a day, with at most 100,000 tokens of examples per call
          (`rate_limited`, with `details.limit`, the limit reached: 20 for the
          judgment's or 50 for the organization's, and `details.resets_at`,
          the next midnight UTC, and no `Retry-After`). A call that fails with
          `engine_unavailable` before the model ran (it was overloaded or
          unreachable) does not count toward either; one that timed out or
          failed after the model replied does.
      operationId: suggestParts
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SuggestPartsRequest'
      responses:
        '200':
          description: The proposed parts.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuggestPartsResponse'
        '400':
          $ref: '#/components/responses/InvalidRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/TooLarge'
        '422':
          $ref: '#/components/responses/InsufficientLabels'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/Internal'
        '503':
          $ref: '#/components/responses/EngineUnavailable'
components:
  parameters:
    Namespace:
      name: ns
      in: path
      required: true
      description: The namespace name, with any `/` sent as `%2F`.
      schema:
        $ref: '#/components/schemas/NamespaceName'
    JudgmentName:
      name: name
      in: path
      required: true
      schema:
        $ref: '#/components/schemas/Name'
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      description: >-
        Returns the original response verbatim while the node still caches it.
        Correctness never depends on it.
      schema:
        type: string
        minLength: 1
  schemas:
    SuggestPartsRequest:
      type: object
      additionalProperties: false
      required:
        - count
      properties:
        count:
          type: integer
          minimum: 2
          maximum: 8
          description: How many parts to propose.
    SuggestPartsResponse:
      type: object
      required:
        - parts
        - examples
      properties:
        parts:
          type: array
          description: >-
            The proposed parts, ready to review, edit and post as a new
            version's `parts`.
          items:
            $ref: '#/components/schemas/JudgmentPart'
        examples:
          type: array
          description: The labelled documents shown to the LLM, at most 30.
          maxItems: 30
          items:
            $ref: '#/components/schemas/DocumentId'
    NamespaceName:
      type: string
      description: >-
        Up to 256 bytes. `/` separates levels of the hierarchy, as in
        `acme/prod/tenant_123`.
      pattern: ^[A-Za-z0-9._:/-]+$
      minLength: 1
      maxLength: 256
    Name:
      type: string
      description: >-
        A judgment, attribute or threshold name. Names are path segments in
        field references, so they never contain `.`.
      pattern: ^[A-Za-z0-9_-]+$
      minLength: 1
      maxLength: 128
    JudgmentPart:
      type: object
      description: One part of a composite judgment (§6.5.1).
      additionalProperties: false
      required:
        - name
        - question
      properties:
        name:
          $ref: '#/components/schemas/Name'
        question:
          type: string
          minLength: 1
          description: A narrow yes/no question about the document.
    DocumentId:
      type: string
      description: Up to 128 bytes.
      pattern: ^[A-Za-z0-9._:/-]+$
      minLength: 1
      maxLength: 128
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
            details:
              type: object
              description: >-
                Code-specific detail, such as the scan estimate on a refused
                query. Every `internal` error has `request_id`.
    ErrorCode:
      type: string
      description: |
        HTTP status by code: `invalid_request` 400, `unauthorized` 401,
        `budget_exceeded` 402, `forbidden` 403, `not_found` 404, `conflict` 409,
        `too_large` 413, `engine_version_unavailable` 422,
        `insufficient_labels` 422, `rate_limited` 429, `internal` 500,
        `engine_unavailable` 503.
      enum:
        - invalid_request
        - unauthorized
        - forbidden
        - not_found
        - conflict
        - too_large
        - rate_limited
        - budget_exceeded
        - engine_unavailable
        - engine_version_unavailable
        - insufficient_labels
        - internal
  headers:
    RateLimitLimit:
      description: Requests allowed per second for this key.
      schema:
        type: integer
        minimum: 0
    RateLimitRemaining:
      description: Requests left in the current window.
      schema:
        type: integer
        minimum: 0
    RetryAfter:
      description: Seconds to wait before retrying.
      schema:
        type: integer
        minimum: 0
  responses:
    InvalidRequest:
      description: '`invalid_request`: the request is malformed or breaks a rule of §6.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: '`unauthorized`: the key is missing, unknown or revoked.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: '`forbidden`: the key''s role or namespace prefix does not allow this.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: '`not_found`: the namespace, document, judgment or job does not exist.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TooLarge:
      description: >-
        `too_large`: the request body (on any route), a document, or the
        estimated query scan is over its limit. `details` carries the estimate
        for queries. It also answers a write that would take
        `default/quickstart` past its size cap (10,000 documents or 100 MB),
        with `details.max_documents` and `details.max_bytes`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InsufficientLabels:
      description: >-
        `insufficient_labels`: the judgment has too few labelled examples
        (outcomes) for this, such as fewer than 10 of either answer for
        suggested parts (§6.5.1). `details` carries the counts.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: >-
        `rate_limited`: slow down. `Retry-After` says for how long, except when
        a daily allowance is used up: then `details.resets_at` says when it
        renews, and there is no `Retry-After`.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Internal:
      description: >-
        `internal`: something failed on our side. Nothing partial is returned,
        and a request never commits part of itself. Most `internal` errors
        committed nothing. A write can instead fail with a message saying it may
        have been committed, when we could not tell whether its batch landed
        (§7.2.10): it then committed all of it or none of it. Retrying a write
        is safe either way, because writes are idempotent. The message is
        generic and carries a request id, also in `details.request_id`, which
        support uses to find the cause.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    EngineUnavailable:
      description: >-
        `engine_unavailable`: the model behind this call is unavailable or
        overloaded, or, on a request naming an engine (a definition or a
        `default_engine`), the engine registry has not loaded yet: the node
        started while it was unreachable. Retry after `Retry-After`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: |
        An organization API key. Keys carry a role (`read_write` or
        `read_only`) and may be restricted to a namespace prefix such as
        `acme/*`, or to one namespace such as `acme/prod/tenant_1`. A prefix
        matches on a `/` boundary: `acme/prod/tenant_1*` covers
        `acme/prod/tenant_1` and everything under `acme/prod/tenant_1/`,
        never `acme/prod/tenant_12`.

````