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

# Annotate a Run

> Attach human signal (rating + required comment + optional target) to a run your org owns. Feeds the same eval corpus the engine learns from.



## OpenAPI

````yaml POST /api/v1/engines/{engine_slug}/runs/{run_id}/annotations
openapi: 3.1.0
info:
  title: Nexio API
  version: '1.0'
  description: |
    Nexio agentic infrastructure API. Configure engines for placement,
    entity analysis, and other patterns. Submit runs, poll for results,
    or subscribe to signed webhook callbacks.
  contact:
    email: support@usenexio.com
    url: https://docs.usenexio.com
servers:
  - url: https://api.usenexio.com
    description: Production
security:
  - BearerAuth: []
tags:
  - name: EngineManagement
    description: Create, configure, and manage inference engines.
  - name: Engines
    description: Engine-scoped endpoints for submitting runs and retrieving results.
  - name: Runs
    description: Retrieve and reconcile submitted runs.
  - name: Catalog
    description: >-
      Read current markets and products extracted for the authenticated
      organization.
  - name: Environments
    description: Isolated tenancy scopes under your org (one live plus non-live sandboxes).
  - name: Webhooks
    description: Manage webhook endpoints for push-based delivery of terminal run events.
  - name: Converse
    description: The raw stateless conversational model turn (caller-owned state).
  - name: Conversations
    description: >-
      Conversation instances (orchestrators over engines) and their managed
      conversations, turns, annotations, evals, and exports.
paths:
  /api/v1/engines/{engine_slug}/runs/{run_id}/annotations:
    post:
      tags:
        - Engines
      summary: Annotate a Run
      description: |
        Attach human signal to a run your org owns: a `rating`
        (`good` / `bad` / `neutral`), a required free-text `comment`, and an
        optional `target` pointer at the specific output element the note is
        about. This is the programmatic counterpart to annotating in the portal,
        and it feeds the same eval corpus the engine learns from.

        Org-scoped by the authenticated API key. A run in another org returns
        `404`. Submissions are stamped `source: api` so customer-API signal is
        distinguishable from portal or review signal.
      operationId: createAnnotation
      parameters:
        - $ref: '#/components/parameters/EngineSlug'
        - in: path
          name: run_id
          required: true
          schema:
            type: string
            format: uuid
          example: bcb87157-0bfc-404d-a120-7f5c9cd01037
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - rating
                - comment
              properties:
                rating:
                  type: string
                  enum:
                    - good
                    - bad
                    - neutral
                comment:
                  type: string
                  description: Required free-text note. Cannot be empty.
                  example: >-
                    Bound the recommended carrier; the ranking matched our
                    judgment.
                target:
                  type: object
                  nullable: true
                  description: Optional pointer at the output element the note is about.
                submitter_id:
                  type: string
                  nullable: true
                  description: >-
                    Optional caller-supplied identifier for who submitted the
                    signal.
                time_on_task_seconds:
                  type: integer
                  nullable: true
      responses:
        '201':
          description: Annotation recorded.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  run_id:
                    type: string
                  rating:
                    type: string
                  comment:
                    type: string
                  source:
                    type: string
                    example: api
                  created_at:
                    type: string
                    format: date-time
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Run not found in this org.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: run_not_found
                message: run not found
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    EngineSlug:
      name: engine_slug
      in: path
      required: true
      description: Engine identifier slug (e.g. `default`).
      schema:
        type: string
  responses:
    BadRequest:
      description: Invalid request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalidRequest:
              summary: Malformed JSON
              value:
                code: invalid_request
                message: Request body is not valid JSON
            invalidInput:
              summary: Input validation failed
              value:
                code: invalid_input
                message: Input failed validation
                details:
                  - field: input.address.state
                    message: address.state is required for placement runs.
            invalidOfferings:
              summary: Placement run missing offerings
              value:
                code: invalid_offerings
                message: Inline offerings failed validation
                details:
                  - field: offerings
                    message: >-
                      Offerings are required for placement runs. Pass provider
                      offerings in the top-level offerings array.
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: unauthorized
            message: Missing or invalid API key
    RateLimited:
      description: Rate limit exceeded. Retry after the window resets.
      headers:
        Retry-After:
          description: Seconds until the rate limit window resets.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: rate_limited
            message: Rate limit exceeded
  schemas:
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: |
            Stable snake_case error identifier. Safe to match programmatically.

            Known codes: `invalid_request`, `invalid_input`, `unauthorized`,
            `auth_unavailable`, `rate_limited`, `missing_run_id`,
            `invalid_run_id`, `run_not_found`, `invalid_offerings`,
            `missing_input`, `queue_unreachable`,
            `engine_not_found`, `engine_slug_conflict`, `engine_archived`,
            `instance_not_found`, `instance_slug_conflict`, `instance_archived`,
            `instance_follows_canonical`, `instance_not_published`,
            `invalid_engine_type`, `validation_error`,
            `webhook_not_found`, `webhook_limit_exceeded`, `invalid_url`,
            `invalid_events`, `invalid_description`, `invalid_auth_token`,
            `missing_endpoint_id`, `invalid_endpoint_id`, `missing_delivery_id`,
            `invalid_delivery_id`, `delivery_not_found`,
            `delivery_not_resendable`, `insufficient_capability`,
            `engine_version_required`, `engine_version_exact_required`,
            `engine_version_not_found`, `engine_version_invalid_format`,
            `engine_version_draft_requires_sandbox_key`,
            `engine_version_none_released`, `test_scenario_sandbox_only`,
            `test_scenario_forbidden`, `test_scenario_exact_version_required`,
            `test_scenario_version_not_supported`, `invalid_test_scenario`,
            `request_bound_exceeded`, and `run_cap_exceeded`.
        message:
          type: string
          description: Human-readable error message. May change between versions.
        details:
          description: |
            Optional request-specific details. Request-bound failures use the
            `RequestBoundDetails` object. Validation failures may use an array
            of field issues or another documented object.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: |
        Send the credential as `Authorization: Bearer <key>`.

        Scoped partner credentials use the exclusive `nxsk_v1_...` namespace.
        Each scoped key is bound at issuance to one organization, one canonical
        named environment, an explicit engine set, and a least-privilege
        capability set. A malformed, unknown, rotated, or revoked `nxsk_` key
        fails closed and is never retried as a legacy key.

        Capabilities used by this API are `runs:write`, `runs:read`,
        `engines:read`, `catalog:read`, `webhooks:manage`,
        `runs:defensibility:read`, `runs:test`, `conversations:use`, and
        `conversations:export`. Operation descriptions name the required
        capability.
        Grandfathered `nx_live_...` and `nx_test_...` keys retain their existing
        broad access during the compatibility window.

````