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

# Apply Case Input

> Review a `suggest` input: accept some rows, optionally with an edited value, and reject the rest. Deterministic, no AI call, applied from the stored record.

- An accepted row is written whatever the fill setting says: a human validated it.
- A row whose field changed on the case since the proposal comes back `skipped` with `reason: value_changed`, so an old proposal never overwrites a newer value.
- Idempotent: rows already applied or rejected are returned unchanged. An unknown row id is a 400.
- `reject_others` (default `true`) rejects every row you did not list. Pass `false` to keep them proposed for a later call.

Review an input created in `suggest` mode: accept some rows, optionally with an edited value, and reject the rest.


## OpenAPI

````yaml POST /cases/{id}/inputs/{input_id}/apply
openapi: 3.0.0
info:
  title: Penbox API
  version: '1.0'
  description: >-
    The Penbox API provides programmatic access to Penbox's form management,
    case management, and document processing capabilities. Authenticate using
    Bearer tokens created at https://app.penbox.io/workspace/settings/api
servers:
  - url: https://connect.penbox.io/v1
    description: Production
security:
  - BearerAuth: []
paths:
  /cases/{id}/inputs/{input_id}/apply:
    post:
      summary: Apply Case Input
      description: >-
        Review a `suggest` input: accept some rows, optionally with an edited
        value, and reject the rest. Deterministic, no AI call, applied from the
        stored record.


        - An accepted row is written whatever the fill setting says: a human
        validated it.

        - A row whose field changed on the case since the proposal comes back
        `skipped` with `reason: value_changed`, so an old proposal never
        overwrites a newer value.

        - Idempotent: rows already applied or rejected are returned unchanged.
        An unknown row id is a 400.

        - `reject_others` (default `true`) rejects every row you did not list.
        Pass `false` to keep them proposed for a later call.
      operationId: apply-case-input
      parameters:
        - name: id
          in: path
          required: true
          description: Case UUID
          schema:
            type: string
            format: uuid
        - name: input_id
          in: path
          required: true
          description: Input UUID
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - changes
              properties:
                changes:
                  type: array
                  items:
                    type: object
                    required:
                      - id
                    properties:
                      id:
                        type: string
                        example: c2
                      value:
                        description: An edited value, validated against the field type
                reject_others:
                  type: boolean
                  default: true
            example:
              changes:
                - id: c1
                - id: c2
                  value: '2026-08-31'
              reject_others: true
      responses:
        '200':
          description: The input with its row statuses updated, plus the refreshed case
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CaseInput'
        '400':
          description: Unknown row id, or an invalid edited value
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    CaseInput:
      type: object
      properties:
        id:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        case:
          type: object
          properties:
            id:
              type: string
              format: uuid
          description: >-
            The case. On the write routes and on the single read it is the full
            case (same shape as `GET /cases/{id}`).
        source:
          type: string
          description: 'Provenance, inferred from your token: `api`'
          example: api
        type:
          type: string
          nullable: true
          enum:
            - call
            - note
            - chat
            - message
            - document
            - other
          description: >-
            What the material is, derived by Penbox from the context and the
            content
        context:
          nullable: true
          description: What you sent as `context`
        mode:
          type: string
          enum:
            - suggest
            - auto
        status:
          type: string
          enum:
            - proposed
            - partially_applied
            - applied
        intelligence:
          type: object
          properties:
            content:
              type: string
              enum:
                - succeeded
                - failed
                - skipped
              description: '`skipped` when the call carried no `content`'
            error:
              type: string
              nullable: true
        summary:
          type: string
          nullable: true
          description: One paragraph on what the material is about, in the case language
        changes:
          type: array
          items:
            $ref: '#/components/schemas/CaseInputChange'
        unmapped:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              value:
                type: string
          description: >-
            Facts read in the content that no case field can hold. Never
            written.
        reviewed_at:
          type: string
          format: date-time
          nullable: true
        content:
          nullable: true
          description: >-
            The raw material, verbatim. Only returned by `GET
            /cases/{id}/inputs/{input_id}`.
    Error:
      type: object
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              status:
                type: string
              title:
                type: string
              detail:
                type: string
              source:
                type: object
                properties:
                  pointer:
                    type: string
    CaseInputChange:
      type: object
      description: One row of the change list. One row, one decision.
      properties:
        id:
          type: string
          description: Stable row id, to pass back to the apply route
          example: c2
        kind:
          type: string
          enum:
            - data
            - contact
            - new_field
            - title
        key:
          type: string
          nullable: true
          description: The case field or contact role. Null on a `title` row.
        label:
          type: string
          nullable: true
        type:
          type: string
          nullable: true
          description: The field type, on `data` and `new_field` rows
        current:
          nullable: true
          description: The value the case held when the input was analysed
        proposed:
          nullable: true
          description: >-
            The value proposed (a string, a number, or a contact object on
            `contact` rows)
        value:
          nullable: true
          description: >-
            What was actually written, once `applied` (the proposal, or the
            reviewer's edit)
        origin:
          type: string
          enum:
            - input
            - ai
          description: '`input`: sent explicitly by the caller. `ai`: read from the content.'
        evidence:
          type: string
          nullable: true
          description: Short verbatim quote supporting an `ai` value
        status:
          type: string
          enum:
            - proposed
            - applied
            - rejected
            - skipped
        reason:
          type: string
          nullable: true
          enum:
            - fill_if_empty
            - fill_never
            - not_extractable
            - create_fields_disabled
            - no_reply_address
            - internal_member
            - main_already_set
            - role_already_set
            - role_not_declared
            - field_exists
            - no_email
            - value_changed
          description: Why a row was `skipped`
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: token
      description: >-
        API token (starts with pnbx_). Create at
        https://app.penbox.io/workspace/settings/api. Include as: Authorization:
        Bearer {token}

````