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

# Answer 1 to N items

> Answer one or more items of the RFI in a single call — each element of `items[]` names its own `item_id`. This is still per-item: each named item gets its own transition and its own event; what you avoid is one round-trip per item for what was, for you, one action (fill the form, submit).

**Marks each item `answered` on receipt** — not when anything downstream accepts it. **All-or-nothing:** every item in the batch is validated against its own `answer_spec` before any of them is written; if one fails, the whole call returns `422` naming which, and the server is left exactly as it was.

Answering a returned item is answering it again with the same `item_id` — a returned item is still `pending`, carrying a `review_note`, and there is no successor RFI or item to discover. A `document` item is never answered here; upload files to it instead (see the document endpoints below). Partial answers are the normal case, not an edge case: answering item 1 and 3 and leaving item 2 is expected.

{/* version-stamp:start — generated by scripts/stamp-versions.ts, do not edit */}

<Info>Stable since **2025-01-01** — unchanged in **2026-06-01**.</Info>

{/* version-stamp:end */}


## OpenAPI

````yaml /openapi/kira-api.2026-06-01.json patch /v1/rfis/{rfi_id}/items
openapi: 3.1.0
info:
  title: Kira API
  version: '2026-06-01'
  description: >-
    REST API for users, KYC/KYB verification, virtual accounts, payouts,
    recipients, and webhooks. Every request requires an `x-api-key` header and a
    bearer access token (see Authentication). Pin your account to version
    `2026-04-14` before integrating.
  contact:
    name: Kira API Support
    email: support@kirafin.ai
servers:
  - url: https://api.balampay.com
    description: Production
  - url: https://api.balampay.com/sandbox
    description: Sandbox
security:
  - bearerAuth: []
    apiKeyAuth: []
tags:
  - name: Authentication
  - name: Versioning
  - name: Users
  - name: Virtual Accounts
  - name: Quotations
  - name: Payouts
  - name: Recipients
  - name: Reference
  - name: RFIs
paths:
  /v1/rfis/{rfi_id}/items:
    patch:
      tags:
        - RFIs
      summary: Answer 1 to N items
      description: >-
        Answer one or more items of the RFI in a single call — each element of
        `items[]` names its own `item_id`. This is still per-item: each named
        item gets its own transition and its own event; what you avoid is one
        round-trip per item for what was, for you, one action (fill the form,
        submit).


        **Marks each item `answered` on receipt** — not when anything downstream
        accepts it. **All-or-nothing:** every item in the batch is validated
        against its own `answer_spec` before any of them is written; if one
        fails, the whole call returns `422` naming which, and the server is left
        exactly as it was.


        Answering a returned item is answering it again with the same `item_id`
        — a returned item is still `pending`, carrying a `review_note`, and
        there is no successor RFI or item to discover. A `document` item is
        never answered here; upload files to it instead (see the document
        endpoints below). Partial answers are the normal case, not an edge case:
        answering item 1 and 3 and leaving item 2 is expected.
      operationId: patch_v1-rfis-rfi-id-items
      parameters:
        - in: path
          name: rfi_id
          required: true
          schema:
            type: string
            format: uuid
          description: RFI UUID.
        - in: header
          name: X-Api-Version
          required: false
          description: >-
            Optional. The date-versioned API version to apply for this request
            (e.g. `2026-04-14`). When sent it always wins, even over your pinned
            account default. When omitted, the API uses your account's pinned
            version if set, otherwise a baseline default.
          schema:
            type: string
            example: '2026-06-01'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RfiItemsAnswerRequest'
            examples:
              answer-two-items:
                summary: Answer two items in one call
                value:
                  items:
                    - item_id: 0198f2c2-0000-0000-0000-000000000000
                      answer_value: 12-3456789
                    - item_id: 0198f2c3-0000-0000-0000-000000000000
                      answer_value: Export sales to three LATAM customers
      responses:
        '200':
          description: All named items were valid and are now answered.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RfiItemsAnswerResponse'
        '400':
          description: >-
            Malformed id, or a malformed body (not `.items[]`, or missing
            `item_id` / `answer_value`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
        '401':
          description: Unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: >-
            The RFI belongs to another client, is `withdrawn`, or an `item_id`
            doesn't belong to this RFI.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >-
            The RFI is already closed (`resolved`, `not_resolved`, or
            `withdrawn`) — it no longer accepts item writes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            At least one item's answer doesn't match its `answer_spec`, an item
            was omitted an empty answer for, or an answer landed in the wrong
            column (e.g. a `document` item sent `answer_value`, or a
            non-`document` item sent files). One entry per failing item;
            **nothing in the batch is written**.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RfiBatchValidationErrorResponse'
      security:
        - bearerAuth: []
          apiKeyAuth: []
components:
  schemas:
    RfiItemsAnswerRequest:
      type: object
      required:
        - items
      properties:
        items:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/RfiItemAnswer'
          description: >-
            1 to N items to answer in one call, each naming its `item_id`.
            Validated against every named item's `answer_spec` before anything
            is written: if any entry fails, the whole batch is rejected with
            `422` and the server is left exactly as it was. A `document` item is
            never answered here — upload files to it instead.
    RfiItemsAnswerResponse:
      type: object
      required:
        - items
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/RfiItem'
          description: >-
            The items named in the request, each reflecting the write (`status:
            "answered"`, `answer_value`/`documents`, `updated_at`).
    ValidationErrorResponse:
      type: object
      description: >-
        Validation / request error. The body shape is **not uniform** across the
        API — it varies by endpoint and by which validation layer rejects the
        request. The fields below are the union of what may appear; treat them
        all as optional. Observed shapes include `{ code, message }`, `{ code,
        message, errors[] }`, `{ code, error, details[] }`, `{ error, details[]
        }`, and a nested `{ error: { code, message, details } }`. Always branch
        on the HTTP status, not on a fixed body shape.
      properties:
        code:
          type: string
        message:
          type: string
        error:
          type:
            - string
            - object
          description: >-
            A short error label (e.g. `"Invalid data"`), or on some endpoints a
            nested `{ code, message, details }` object.
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string
            required:
              - field
              - message
        details:
          type:
            - array
            - object
          description: >-
            Per-issue detail. Shape varies by endpoint — typically an array of
            `{ message }` or `{ path, message, code }`, occasionally an object.
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
        code:
          type: string
        statusCode:
          type: number
        error:
          type: string
        timestamp:
          type: string
        path:
          type: string
        details: {}
      required:
        - message
    RfiBatchValidationErrorResponse:
      type: object
      description: >-
        All-or-nothing batch rejection: at least one item in the batch failed
        validation and nothing in the batch was written.
      required:
        - errors
      properties:
        errors:
          type: array
          items:
            type: object
            required:
              - item_id
              - message
            properties:
              item_id:
                type: string
                format: uuid
              message:
                type: string
                description: >-
                  One-line, human-readable reason this item's answer was
                  rejected.
    RfiItemAnswer:
      type: object
      required:
        - item_id
        - answer_value
      properties:
        item_id:
          type: string
          format: uuid
        answer_value:
          description: >-
            The answer for this item, in the shape its `answer_type` expects (a
            string for `text_short` / `text_long` / `identifier`, etc. —
            validated against `answer_spec`). Required: there is no empty
            answer.
    RfiItem:
      type: object
      description: >-
        One thing being asked for. The addressable unit of an RFI — a `PATCH` or
        a document upload always names an `item_id`, never the parent RFI.
      required:
        - item_id
        - ordinal
        - prompt
        - answer_type
        - answer_spec
        - target_key
        - status
        - answer_value
        - documents
        - review_note
        - updated_at
        - returned_at
      properties:
        item_id:
          type: string
          format: uuid
        ordinal:
          type: integer
          description: Display order within the RFI.
        prompt:
          type: string
          description: What is being asked, in prose.
        answer_type:
          type: string
          enum:
            - text_long
            - text_short
            - number
            - date
            - boolean
            - choice
            - identifier
            - document
          description: >-
            The shape the answer must take. Closed by a database `CHECK`, not
            just this schema.
        answer_spec:
          type: object
          additionalProperties: true
          description: >-
            Configuration for `answer_type`, closed per type — the full set of
            keys the item will validate an answer against, not a suggestion. A
            new question shape is data here, never a contract change. Only two
            shapes are contract-fixed today: `document` (`mime_types: string[]`,
            `max_files: integer`) and `identifier` (`format: string`, e.g.
            `"ein"`). The `answer_spec` shape for `text_long` / `text_short` /
            `number` / `date` / `boolean` / `choice` is implementation-defined
            and not yet fixed by this contract — confirm before building against
            it.
          example:
            mime_types:
              - application/pdf
            max_files: 5
        target_key:
          type:
            - string
            - 'null'
          description: >-
            The named subclient field this answer writes on acceptance (e.g.
            `ein`), or `null` when the answer lives only on this item.
        status:
          type: string
          enum:
            - pending
            - answered
          description: >-
            `pending` — awaiting your answer, whether never answered or returned
            for a fix (see `review_note`). `answered` — submitted, in review. An
            item carries no terminal state of its own — whether the RFI as a
            whole is satisfied is `rfi.status`, not this column.
        answer_value:
          type:
            - string
            - number
            - boolean
            - 'null'
          description: >-
            The submitted answer, in the shape `answer_type` expects: a JSON
            string for `text_short` / `text_long` / `date` / `choice` /
            `identifier`, a JSON number for `number`, a JSON boolean for
            `boolean`. `null` only for a `document` item, whose answer lives in
            `documents[]` instead.
        documents:
          type: array
          items:
            $ref: '#/components/schemas/RfiDocument'
          description: Always present; empty unless `answer_type` is `document`.
        review_note:
          type:
            - string
            - 'null'
          description: >-
            Why the analyst returned this item for another answer. Set while
            `status` is `pending` as the result of a return; cleared the next
            time the item is answered.
        updated_at:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            When this item was last answered. Moves on every round, whether or
            not it changes the item's status.
        returned_at:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            When an analyst last sent this item back for another answer. Null if
            it has never been returned — including while it's under review,
            since a pass-through review stamps nothing here.
    RfiDocument:
      type: object
      description: >-
        A file attached to a `document` item's response. `uploaded_by` is never
        echoed here: it always resolves to your own API key (the subclient never
        calls this API directly), so a field that always reads back "you"
        carries nothing for the reader — the same reasoning the contract applies
        to `client_uuid`.
      required:
        - document_id
        - file_name
        - mime_type
        - size_bytes
        - uploaded_at
      properties:
        document_id:
          type: string
          format: uuid
        file_name:
          type: string
          description: >-
            The name the file was uploaded under, sanitized. This is the name it
            downloads as — the internal storage path is never exposed.
          example: january.pdf
        mime_type:
          type: string
          example: application/pdf
        size_bytes:
          type: integer
        checksum:
          type: string
          description: Content hash of the uploaded file.
        uploaded_at:
          type: string
          format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Access token from `POST /auth` (the `data.access_token` value).
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key issued by Kira. Required on every request, including `/auth`.

````