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

# Record an externally-observed fact about an assignment set

> Records a fact the operator confirms and moves the set accordingly. offer_sent confirms the authorized offer file was delivered to the fund's administrator, and requires an authorized file to exist and the newest one to cover the lines still in the lot and, when the confirmation names the file sent (offerFileId), to be that file (LENDER-1505); once a later download replaced a file, the confirmation must name it. paid, transferred and accepted are per-receivable and follow one another in that order once the set's payment is open: for a fund whose administrator generates the term, as soon as the fund's return file is accepted; for a fund the Lender emits for, once that term is signed. Each names where it came from, and each applies either to named receivables or to the whole surviving composition. accepted is the flip: the contract leaves this portfolio and its write-off is enqueued in the SAME transaction, or neither happens. A repeated confirmation is inert and reported as replayed rather than recording a second send or a second write-off. Re-stating paid is also the way to re-issue a title transfer the registradora refused: the fact writes nothing the second time, while the registry command is reached again through its own deterministic reference. Only a transferred fact whose provenance is registry_provider settles that command — the acceptance's proof of a moved title is the registradora's own statement and nobody else's. paid states amountPaid, what the bank shows the fund sent for the lot; while it differs, net of the desk's refunds for lines taken out, from the frozen prices of the paid lines still in the lot by more than the lot's tolerance, the title transfer waits and the acceptance is held (LENDER-0511). Settling the payment commands no title for a line under an open dead-line case. accepted is refused while a line still in the lot is not paid (LENDER-0516). Once a line of the lot is accepted, a paid that states a new amount is refused (LENDER-0515): money the fund sends after is settled at the exception desk.



## OpenAPI

````yaml /pt/openapi/v3-current/lender.yaml post /api/v1/assignment/sets/{setId}/facts
openapi: 3.1.0
info:
  contact:
    email: contact@lerian.studio
    name: Lerian Studio
    url: https://lerian.studio
  description: >-
    Code-first OpenAPI 3.1 surface for the Lender service. Routes that move
    money are at-most-once per X-Idempotency: when one answers 5xx, the
    X-Idempotency-Fenced response header says whether that key is now refusing
    resends (true) or free to retry (false or absent).
  license:
    name: Lerian Studio General License
  title: Lender API
  version: 1.0.0
servers:
  - url: https://lender.sandbox.lerian.net
security:
  - BearerAuth: []
tags:
  - description: >-
      Caller session projection: validated subject and effective permissions for
      the presented token.
    name: Session
  - description: >-
      Ledger accounting operations: journal entries and accrual postings for
      loan accounts. Operations under /api/v1/internal are back-office
      operations for the client's operators: they require a person's login, and
      a service credential gets 403.
    name: Accounting
  - description: >-
      Loan application intake and lifecycle: submission, decisioning, and
      status.
    name: LoanApplications
  - description: >-
      Loan product catalog: definition, versioning, and activation of lending
      products.
    name: LoanProducts
  - description: >-
      Loan account servicing operations: balances, schedules, and account-level
      actions.
    name: Loan Accounts
  - description: >-
      Portfolio dashboard read operations: aggregated portfolio and performance
      views.
    name: Dashboard
  - description: >-
      Jurisdiction registry: supported jurisdiction profiles and their
      capabilities.
    name: Jurisdictions
  - description: >-
      Jurisdiction-specific loan application operations (Brazil origination
      surface).
    name: Loan Applications
  - description: >-
      Tax computation operations for jurisdiction-specific lending (e.g. Brazil
      IOF).
    name: Tax
  - description: >-
      Brazil consignado privado operations: contract lifecycle, exclusion
      repair, and compensating adjustments. Operations under /api/v1/internal
      are back-office operations for the client's operators: they require a
      person's login, and a service credential gets 403.
    name: Consignado
  - description: >-
      Inbound record quarantine. Operations under /api/v1/internal are
      back-office operations for the client's operators: they require a person's
      login, and a service credential gets 403.
    name: Streaming
  - description: >-
      Credit-instrument document template registry: versioned drafting and
      publication of CCB clausulado.
    name: DocumentTemplates
paths:
  /api/v1/assignment/sets/{setId}/facts:
    post:
      tags:
        - AssignmentSets
      summary: Record an externally-observed fact about an assignment set
      description: >-
        Records a fact the operator confirms and moves the set accordingly.
        offer_sent confirms the authorized offer file was delivered to the
        fund's administrator, and requires an authorized file to exist and the
        newest one to cover the lines still in the lot and, when the
        confirmation names the file sent (offerFileId), to be that file
        (LENDER-1505); once a later download replaced a file, the confirmation
        must name it. paid, transferred and accepted are per-receivable and
        follow one another in that order once the set's payment is open: for a
        fund whose administrator generates the term, as soon as the fund's
        return file is accepted; for a fund the Lender emits for, once that term
        is signed. Each names where it came from, and each applies either to
        named receivables or to the whole surviving composition. accepted is the
        flip: the contract leaves this portfolio and its write-off is enqueued
        in the SAME transaction, or neither happens. A repeated confirmation is
        inert and reported as replayed rather than recording a second send or a
        second write-off. Re-stating paid is also the way to re-issue a title
        transfer the registradora refused: the fact writes nothing the second
        time, while the registry command is reached again through its own
        deterministic reference. Only a transferred fact whose provenance is
        registry_provider settles that command — the acceptance's proof of a
        moved title is the registradora's own statement and nobody else's. paid
        states amountPaid, what the bank shows the fund sent for the lot; while
        it differs, net of the desk's refunds for lines taken out, from the
        frozen prices of the paid lines still in the lot by more than the lot's
        tolerance, the title transfer waits and the acceptance is held
        (LENDER-0511). Settling the payment commands no title for a line under
        an open dead-line case. accepted is refused while a line still in the
        lot is not paid (LENDER-0516). Once a line of the lot is accepted, a
        paid that states a new amount is refused (LENDER-0515): money the fund
        sends after is settled at the exception desk.
      operationId: recordAssignmentSetFact
      parameters:
        - description: Assignment set identifier.
          in: path
          name: setId
          required: true
          schema:
            description: Assignment set identifier.
            format: uuid
            type: string
        - description: >-
            Canonical idempotency request ID. Required: this request moves
            money, and without a key a retry cannot be told apart from a second
            instruction.
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: >-
              Canonical idempotency request ID. Required: this request moves
              money, and without a key a retry cannot be told apart from a
              second instruction.
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecordAssignmentSetFactHumaInputBody'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssignmentSetFactHumaBody'
          description: OK
          headers:
            X-Idempotency-Replayed:
              description: >-
                "true" when this response replays a request already executed
                under the same X-Idempotency, so nothing ran a second time and
                no money moved again. Absent on a first execution.
              schema:
                type: string
        '400':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: >-
            The at-most-once contract refused the request before any handler
            ran: no X-Idempotency header (IDEMPOTENCY_KEY_REQUIRED), a key under
            a spelling this service does not read
            (IDEMPOTENCY_KEY_HEADER_UNKNOWN), or a request that could not be
            scoped to a tenant (IDEMPOTENCY_TENANT_REQUIRED). The code is in the
            problem document's `code` member.
        '401':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Unauthorized
        '403':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Forbidden
        '404':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Not Found
        '413':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Request Entity Too Large
        '422':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Unprocessable Entity
        '500':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Internal Server Error
        '503':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Service Unavailable
        '504':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Gateway Timeout
        default:
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Error
components:
  schemas:
    RecordAssignmentSetFactHumaInputBody:
      additionalProperties: false
      properties:
        acceptance:
          $ref: '#/components/schemas/AssignmentAcceptanceHumaBody'
          description: >-
            The administrator's acceptance document, in the pinned shape.
            Required when factType is accepted and provenance is
            administrator_file.
        amountPaid:
          description: >-
            What the fund sent for the lot in all, as the bank shows it, less
            only what the desk refunded it for an over-payment. Never subtract
            refundToFund: the Lender keeps what the desk settles for lines taken
            out through their case apart and nets it itself. Decimal string in
            the lot's currency, above zero, at most 2 decimal places. REQUIRED
            on paid and refused on any other fact (LENDER-0510). The latest
            statement wins until a line of the lot is accepted; after that it
            stands (LENDER-0515). While it differs, net of those refunds, from
            the frozen prices of the paid lines still in the lot by more than
            the tolerance the lot froze from its fund, a fund_payment_divergence
            case is open, the title transfer waits and the acceptance is held
            (LENDER-0511).
          type: string
        factType:
          description: >-
            The externally-observed fact being confirmed. offer_sent is the
            operator confirming the authorized offer file was delivered to the
            fund's administrator, and requires an authorized file to exist.
            paid, transferred and accepted are per-receivable progress facts and
            follow one another in that order; accepted is the administrator
            accepting the title transfer, which takes the receivable out of this
            portfolio and writes it off. term_signed is NOT here: it is derived
            from the signed endorsement instrument itself.
          enum:
            - offer_sent
            - paid
            - transferred
            - accepted
          type: string
        offerFileId:
          description: >-
            The X-Offer-File-Id of the offer file that was sent. On offer_sent,
            when present, it must be the newest file authorized for the lot, or
            nothing is recorded (LENDER-1505): a file another download replaced
            is not the offer the Lender serves as sent, and a repeated
            confirmation naming it is refused too. Required on offer_sent once
            the lot holds more than one authorized file, which happens when a
            line left the lot and a later download replaced the file. Ignored on
            any other fact.
          format: uuid
          type: string
        provenance:
          description: >-
            Where the fact came from. REQUIRED for paid, transferred and
            accepted; ignored for offer_sent, which is by construction an
            operator's own confirmation about a file we generated. On a
            transferred fact it also decides whether the registradora's
            title-transfer command is settled: only registry_provider does that,
            because the acceptance guard treats a settled command as proof the
            title moved, and a desk's or an administrator's own statement is not
            the registradora's acatamento. Where the fund reaches no
            registradora the guard does not apply at all.
          enum:
            - administrator_file
            - registry_provider
            - operator
          type: string
        receivableRefs:
          description: >-
            Narrows a per-receivable fact to exactly these receivables. Omit it
            to mean the WHOLE surviving composition — the honest reading of an
            administrator stating that a portfolio was paid. A reference the set
            does not carry, or carries as cut or removed, is refused. It must be
            EMPTY when an acceptance document is present: the document already
            names what was accepted, and two lists are two answers.
          items:
            maxLength: 128
            minLength: 1
            pattern: \S
            type: string
          maxItems: 500
          type:
            - array
            - 'null'
      required:
        - factType
      type: object
    AssignmentSetFactHumaBody:
      additionalProperties: false
      properties:
        assignmentSetId:
          description: The set the fact was recorded against.
          type: string
        derecognizedRefs:
          description: >-
            The receivables this call wrote off the balance sheet: contracts
            that left this portfolio with their write-off enqueued in the same
            transaction.
          items:
            type: string
          type:
            - array
            - 'null'
        factType:
          description: The fact that was confirmed.
          type: string
        fromState:
          description: The lifecycle state the set was in.
          type: string
        provenance:
          description: Where the fact came from, echoed back for the audit trail.
          type: string
        recordedBy:
          description: Validated actor identity that confirmed the fact.
          type: string
        recordedRefs:
          description: >-
            The receivables this call actually recorded the fact for, excluding
            the ones that already carried it.
          items:
            type: string
          type:
            - array
            - 'null'
        replayed:
          description: >-
            True when nothing was written: the set was already in the resulting
            state, or every receivable named already carried the fact. A
            repeated confirmation never records a second send and never enqueues
            a second write-off.
          type: boolean
        toState:
          description: >-
            The lifecycle state the fact moved it to. It advances only once
            EVERY surviving receivable carries the fact.
          type: string
      required:
        - assignmentSetId
        - factType
        - fromState
        - toState
        - recordedBy
        - replayed
      type: object
    Detail:
      additionalProperties: true
      properties:
        code:
          description: >-
            Stable, machine-readable domain error code scoped to the emitting
            service (format: <SERVICE>-NNNN).
          type: string
        detail:
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          examples:
            - Property foo is required but is missing.
          type: string
        errors:
          description: Optional list of individual error details
          items:
            $ref: '#/components/schemas/ErrorDetail'
          type:
            - array
            - 'null'
        instance:
          description: >-
            A URI reference that identifies the specific occurrence of the
            problem.
          examples:
            - https://example.com/error-log/abc123
          format: uri
          type: string
        status:
          description: HTTP status code
          examples:
            - 400
          format: int64
          type: integer
        title:
          description: >-
            A short, human-readable summary of the problem type. This value
            should not change between occurrences of the error.
          examples:
            - Bad Request
          type: string
        type:
          default: about:blank
          description: A URI reference to human-readable documentation for the error.
          examples:
            - https://example.com/errors/example
          format: uri
          type: string
        upstream:
          $ref: '#/components/schemas/Upstream'
          description: >-
            RFC 9457 extension member: the error a proxied third-party provider
            reported. Absent unless the emitting service explicitly surfaced
            one.
      type: object
    AssignmentAcceptanceHumaBody:
      additionalProperties: false
      properties:
        acceptedAt:
          description: >-
            When the administrator says the acceptance happened (RFC3339). It is
            EVIDENCE, not the lifecycle clock: the fact's own instant stays the
            moment the confirmation reached us, so nothing a counterparty sends
            can backdate a write-off.
          format: date-time
          type: string
        acceptedBy:
          description: >-
            The ADMINISTRATOR's own identity for whoever accepted. It never
            substitutes for our validated actor, which is recorded beside it.
          maxLength: 256
          type: string
        assignmentSetId:
          description: The set the administrator accepted. Must match the set on the route.
          format: uuid
          type: string
        receivableRefs:
          description: >-
            The receivables the administrator accepted. An acatamento always
            names them: 'the whole set' is a convenience our own operators may
            use, never a claim inferred on an administrator's behalf.
          items:
            type: string
          maxItems: 500
          minItems: 1
          type:
            - array
            - 'null'
        transferReference:
          description: >-
            The ADMINISTRATOR's own reference for this acatamento — its batch
            protocol, its file id, whatever it can be quoted back by. One
            reference for the whole document under both regimes: an
            administrator does not move titles at a registradora and has no
            per-title protocol to give. Where a registradora governs, each
            receivable's fact row also carries OUR confirmed per-title protocol
            beside this one.
          maxLength: 256
          type: string
      required:
        - assignmentSetId
        - receivableRefs
        - acceptedBy
        - acceptedAt
        - transferReference
      type: object
    ErrorDetail:
      additionalProperties: false
      properties:
        location:
          description: >-
            Where the error occurred, e.g. 'body.items[3].tags' or
            'path.thing-id'
          type: string
        message:
          description: Error message text
          type: string
        value:
          description: The value at the given location
      type: object
    Upstream:
      additionalProperties: false
      properties:
        code:
          description: The upstream provider's own error code, verbatim.
          examples:
            - E4001
          type: string
        message:
          description: >-
            The upstream provider's own error message, verbatim (bounded, never
            its raw response body).
          examples:
            - account not found at provider
          type: string
      type: object
  securitySchemes:
    BearerAuth:
      bearerFormat: JWT
      description: JWT bearer token issued by the identity provider.
      scheme: bearer
      type: http

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.