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

# Mint a beneficiary's verification link

> Mint a link for a `ubo_link` item whose `answer_spec` carries `applicant_id` rather than a ready-made `url` — see [RFI values](/reference/rfis/values#the-two-ubo_link-shapes).

Each link is short-lived, so mint one when the person clicks rather than when the page renders.



## OpenAPI

````yaml /openapi/kira-api.2026-04-14.json post /v1/rfis/{rfi_id}/items/{item_id}/ubo-link
openapi: 3.1.0
info:
  title: Kira API
  version: '2026-04-14'
  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: Recipients
  - name: Quotations
  - name: Payouts
  - name: Reference
  - name: RFIs
paths:
  /v1/rfis/{rfi_id}/items/{item_id}/ubo-link:
    post:
      tags:
        - RFIs
      summary: Mint a beneficiary's verification link
      description: >-
        Mint a link for a `ubo_link` item whose `answer_spec` carries
        `applicant_id` rather than a ready-made `url` — see [RFI
        values](/reference/rfis/values#the-two-ubo_link-shapes).


        Each link is short-lived, so mint one when the person clicks rather than
        when the page renders.
      operationId: post_v1-rfis-rfi-id-items-item-id-ubo-link
      parameters:
        - in: path
          name: rfi_id
          required: true
          schema:
            type: string
            format: uuid
          description: RFI UUID.
        - in: path
          name: item_id
          required: true
          schema:
            type: string
            format: uuid
          description: >-
            Item UUID. Must be a `ubo_link` item of this RFI whose `answer_spec`
            carries `applicant_id`, not a pasted `url`.
        - in: header
          name: X-Api-Version
          required: false
          schema:
            type: string
            example: '2026-04-14'
          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.
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RfiUboLinkResponse'
              example:
                url: >-
                  https://identity.example.com/websdk/p/aGVsbG8tdGhlcmU?t=eyJhbGciOi…
                expires_at: '2026-09-11T12:00:00.000Z'
          description: The link was minted.
        '400':
          description: >-
            An id in the path is not a UUID. Ids are checked before anything is
            looked up, so a malformed one answers `400`, not `404`. This body
            has `error` and `details[]`, and no `code`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
              example:
                error: Invalid request data
                details:
                  - path: rfi_id
                    message: Invalid RFI ID format
                    code: invalid_string
        '401':
          description: Unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: invalid_request
                message: >-
                  The request could not be authenticated. Check the x-api-key
                  and Authorization headers.
        '404':
          description: >-
            The request is not visible to you — another client's, or withdrawn —
            or the item does not belong to it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                rfi_not_found:
                  summary: The request is not yours, or was withdrawn
                  value:
                    statusCode: 404
                    error: Not Found
                    message: RFI not found
                    timestamp: '2026-09-15T10:22:41.117Z'
                    path: >-
                      /v1/rfis/7f1c9a20-3b4d-4e5f-8a91-2c3d4e5f6a7b/items/1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b/ubo-link
                    code: rfi_not_found
                item_not_found:
                  summary: The item is not on this request
                  value:
                    statusCode: 404
                    error: Not Found
                    message: >-
                      item 1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b does not belong
                      to rfi 7f1c9a20-3b4d-4e5f-8a91-2c3d4e5f6a7b
                    timestamp: '2026-09-15T10:22:41.117Z'
                    path: >-
                      /v1/rfis/7f1c9a20-3b4d-4e5f-8a91-2c3d4e5f6a7b/items/1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b/ubo-link
                    code: rfi_item_not_found
        '409':
          description: >-
            The request is closed, so the beneficial owner it was waiting on is
            no longer needed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                statusCode: 409
                error: Conflict
                message: >-
                  rfi 7f1c9a20-3b4d-4e5f-8a91-2c3d4e5f6a7b is resolved and no
                  longer needs this beneficiary
                timestamp: '2026-09-15T10:22:41.117Z'
                path: >-
                  /v1/rfis/7f1c9a20-3b4d-4e5f-8a91-2c3d4e5f6a7b/items/1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b/ubo-link
                code: rfi_closed
        '422':
          description: >-
            No link could be minted for this item. Read `code`. The item may not
            be a `ubo_link`, or it may be an older one that already carries a
            `url` in its `answer_spec`: show that link instead of calling this.
            The last two examples mean the mint itself did not go through. Retry
            once before you tell your customer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                not_ubo_link:
                  summary: The item does not ask for a beneficial owner
                  value:
                    statusCode: 422
                    error: Unprocessable Entity
                    message: >-
                      item 1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b does not ask for
                      a beneficiary to be registered
                    timestamp: '2026-09-15T10:22:41.117Z'
                    path: >-
                      /v1/rfis/7f1c9a20-3b4d-4e5f-8a91-2c3d4e5f6a7b/items/1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b/ubo-link
                    code: rfi_item_not_ubo_link
                not_mintable:
                  summary: The item already carries its own link
                  value:
                    statusCode: 422
                    error: Unprocessable Entity
                    message: >-
                      item 1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b carries its link
                      already and does not mint one
                    timestamp: '2026-09-15T10:22:41.117Z'
                    path: >-
                      /v1/rfis/7f1c9a20-3b4d-4e5f-8a91-2c3d4e5f6a7b/items/1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b/ubo-link
                    code: rfi_item_ubo_link_not_mintable
                applicant_incomplete:
                  summary: The person's verification record is not ready to be linked
                  value:
                    statusCode: 422
                    error: Unprocessable Entity
                    message: >-
                      the beneficiary's verification record is not ready for a
                      link
                    timestamp: '2026-09-15T10:22:41.117Z'
                    path: >-
                      /v1/rfis/7f1c9a20-3b4d-4e5f-8a91-2c3d4e5f6a7b/items/1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b/ubo-link
                    code: rfi_ubo_link_applicant_incomplete
                not_minted:
                  summary: No link came back
                  value:
                    statusCode: 422
                    error: Unprocessable Entity
                    message: no verification link was issued for this beneficiary
                    timestamp: '2026-09-15T10:22:41.117Z'
                    path: >-
                      /v1/rfis/7f1c9a20-3b4d-4e5f-8a91-2c3d4e5f6a7b/items/1a2b3c4d-5e6f-4708-9a1b-2c3d4e5f6a7b/ubo-link
                    code: rfi_ubo_link_not_minted
      security:
        - bearerAuth: []
          apiKeyAuth: []
      servers:
        - url: https://api.balampay.com/sandbox
          description: Sandbox
        - url: https://api.balampay.com
          description: Production
components:
  schemas:
    RfiUboLinkResponse:
      type: object
      properties:
        url:
          type: string
          format: uri
          description: >-
            An `https` link to the identity-verification page for the person to
            open. Render it as a link, not a form field: nothing comes back
            through this API, and the item closes on its own once they finish.
            The host belongs to the service that runs the check rather than to
            Kira, so open the link exactly as it arrives and never rebuild it
            from parts.
        expires_at:
          type: string
          format: date-time
          description: >-
            When this specific link stops working — about an hour out, though
            read the field rather than hard-coding that. Past it, mint a new one
            instead of reusing this one.
    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
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        The `data.access_token` value from [Get access
        token](/api-reference/authentication/get-access-token).
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key issued by Kira.

````