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

# List Retained TED IN Messages

> Use this endpoint to list the inbound JD messages that this service neither credited nor returned, oldest first, so an operator can see what is stuck, why, for how long, and how much money is behind it.

By default (`state=open`) the list shows only what is still open. A retention closed through [Close Unsettled TED IN Credit](/en/reference/interfaces/ted-jd/close-unsettled-ted-in-credit) leaves this list and every retained gauge, which lets an alert on those numbers clear. `state=closed` or `state=all` bring the closed rows back, each with its outcome, its note, and the person who wrote it.

Six retention reasons are written. A person ends four of them:

- `UNRECOGNIZED_TYPE`: the message type is not one that this service consumes.
- `ACCOUNT_NOT_OWNED`: the recipient account is not one that this service owns.
- `CLASSIFICATION_FAILED`: the credit carries an amount that nothing can credit.
- `RECIPIENT_NOT_FOUND_RETURN_UNAUTHORIZED`: the recipient was not found, and the tenant has not authorized the automatic return to the clearing house.

Two end by themselves and carry `drained: false`:

- `LEDGER_ROUTE_UNRESOLVED`: no ledger routing binding answers the organization, ledger, and transfer type that the credit was refused for (`TED_OUT` for a chargeback compensation, which debits the beneficiary).
- `RECIPIENT_AMBIGUOUS_ORGANIZATIONS`: the recipient sits in several of the tenant's own organizations under the receiving ISPB.

These two are written only when the tenant's database carries the current migrations. Before that, a routing hold writes no row and appears on no list, so an empty list does not prove that no credit is held. The poller asks their question again on every cycle. When the configuration answers it, the credit lands and the row leaves this list with no operator action, so the close endpoint refuses them with BTF-0217. That check does not see a recipient re-homed in CRM: after such a repair, call [Replay TED IN Backlog](/en/reference/interfaces/ted-jd/replay-ted-in-poll), which re-drives every held row once. A credit held because the ISPB-to-organization binding could not be read writes no row and is not listed here. It lands by itself once the read recovers.

The `reason` filter also accepts `ACCOUNT_UNASSIGNED`, `AMBIGUOUS_CONTROL_ID`, and `OWNERSHIP_DECISION_UNAVAILABLE`. No row carries these reasons, so a filter on one of them returns an empty list.

Returning funds is irreversible; retention is not. Nothing from the original message is rendered: `contentBytes` says how much is held without showing any of it. A closed row carries the operator's note verbatim. The note is free text that a member of staff wrote about their own decision, 10 to 500 characters, never derived from the message and not sanitized. The retained records kept on the undeliverable side are listed by [List Undeliverable TED IN Credits](/en/reference/interfaces/ted-jd/list-undeliverable-ted-in-credits) with `status=RETAINED`.

This is a read-only administrative endpoint. It does not require the `X-Organization-Id` header. In multi-tenant deployments the list is scoped to the caller's resolved tenant database.



## OpenAPI

````yaml /pt/openapi/v3-current/ted.yaml get /v1/transfers/ted-in/retained
openapi: 3.0.3
info:
  title: Bank Transfer (TED) Plugin API
  description: >-
    Complete API for Brazilian bank transfers (TED OUT, TED IN, P2P) through the
    Lerian platform, including transfer initiation, processing, status tracking,
    and cancellation.
  version: 1.1.9
servers:
  - url: https://ted.sandbox.lerian.net
    description: Sandbox (placeholder — not yet available for public access)
security:
  - BearerAuth: []
  - OAuth2ClientCredentials:
      - api
  - OAuth2Password:
      - api
tags:
  - name: Transfers API
    description: Endpoints for initiating, processing, tracking, and cancelling transfers.
  - name: Webhooks
    description: >-
      Endpoints for registering and managing tenant-scoped webhook subscriptions
      for transfer events.
  - name: Webhook DLQ
    description: Endpoints for inspecting and retrying webhook dead-letter queue messages.
paths:
  /v1/transfers/ted-in/retained:
    get:
      tags:
        - Transfers API
      summary: List Retained TED IN Messages
      description: >-
        Use this endpoint to list the inbound JD messages that this service
        neither credited nor returned, oldest first, so an operator can see what
        is stuck, why, for how long, and how much money is behind it.


        By default (`state=open`) the list shows only what is still open. A
        retention closed through [Close Unsettled TED IN
        Credit](/en/reference/interfaces/ted-jd/close-unsettled-ted-in-credit)
        leaves this list and every retained gauge, which lets an alert on those
        numbers clear. `state=closed` or `state=all` bring the closed rows back,
        each with its outcome, its note, and the person who wrote it.


        Six retention reasons are written. A person ends four of them:


        - `UNRECOGNIZED_TYPE`: the message type is not one that this service
        consumes.

        - `ACCOUNT_NOT_OWNED`: the recipient account is not one that this
        service owns.

        - `CLASSIFICATION_FAILED`: the credit carries an amount that nothing can
        credit.

        - `RECIPIENT_NOT_FOUND_RETURN_UNAUTHORIZED`: the recipient was not
        found, and the tenant has not authorized the automatic return to the
        clearing house.


        Two end by themselves and carry `drained: false`:


        - `LEDGER_ROUTE_UNRESOLVED`: no ledger routing binding answers the
        organization, ledger, and transfer type that the credit was refused for
        (`TED_OUT` for a chargeback compensation, which debits the beneficiary).

        - `RECIPIENT_AMBIGUOUS_ORGANIZATIONS`: the recipient sits in several of
        the tenant's own organizations under the receiving ISPB.


        These two are written only when the tenant's database carries the
        current migrations. Before that, a routing hold writes no row and
        appears on no list, so an empty list does not prove that no credit is
        held. The poller asks their question again on every cycle. When the
        configuration answers it, the credit lands and the row leaves this list
        with no operator action, so the close endpoint refuses them with
        BTF-0217. That check does not see a recipient re-homed in CRM: after
        such a repair, call [Replay TED IN
        Backlog](/en/reference/interfaces/ted-jd/replay-ted-in-poll), which
        re-drives every held row once. A credit held because the
        ISPB-to-organization binding could not be read writes no row and is not
        listed here. It lands by itself once the read recovers.


        The `reason` filter also accepts `ACCOUNT_UNASSIGNED`,
        `AMBIGUOUS_CONTROL_ID`, and `OWNERSHIP_DECISION_UNAVAILABLE`. No row
        carries these reasons, so a filter on one of them returns an empty list.


        Returning funds is irreversible; retention is not. Nothing from the
        original message is rendered: `contentBytes` says how much is held
        without showing any of it. A closed row carries the operator's note
        verbatim. The note is free text that a member of staff wrote about their
        own decision, 10 to 500 characters, never derived from the message and
        not sanitized. The retained records kept on the undeliverable side are
        listed by [List Undeliverable TED IN
        Credits](/en/reference/interfaces/ted-jd/list-undeliverable-ted-in-credits)
        with `status=RETAINED`.


        This is a read-only administrative endpoint. It does not require the
        `X-Organization-Id` header. In multi-tenant deployments the list is
        scoped to the caller's resolved tenant database.
      operationId: listRetainedTEDInMessages
      parameters:
        - name: reason
          in: query
          description: Filter by retention reason.
          schema:
            type: string
            enum:
              - UNRECOGNIZED_TYPE
              - ACCOUNT_NOT_OWNED
              - ACCOUNT_UNASSIGNED
              - RECIPIENT_NOT_FOUND_RETURN_UNAUTHORIZED
              - CLASSIFICATION_FAILED
              - AMBIGUOUS_CONTROL_ID
              - LEDGER_ROUTE_UNRESOLVED
              - RECIPIENT_AMBIGUOUS_ORGANIZATIONS
              - OWNERSHIP_DECISION_UNAVAILABLE
        - name: state
          in: query
          description: >-
            Closure window. `open` (default) is what is still stuck and what
            every retained gauge counts; `closed` is what an operator already
            settled, with who, when, and how; `all` is both.
          schema:
            type: string
            enum:
              - open
              - closed
              - all
            default: open
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
        - name: offset
          in: query
          description: >-
            Number of records to skip for pagination. Advance it by the
            `returned` value of the previous page.
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: >-
            Indicates that the request was successful and the matching retained
            messages are returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RetainedTEDInMessageList'
        '400':
          description: >-
            BTF-0001: the tenant context or a query parameter is invalid.
            BTF-0210: the retention reason is outside the declared vocabulary.
            BTF-0214: `state` is not `open`, `closed`, or `all`.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDocument'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          description: >-
            BTF-9005: the retained-message reader is not configured in this
            deployment.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDocument'
components:
  schemas:
    RetainedTEDInMessageList:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/RetainedTEDInMessage'
        pagination:
          $ref: '#/components/schemas/PaginationInfo'
    ProblemDocument:
      type: object
      description: >-
        The RFC 9457 problem document that the service answers every error with,
        on `application/problem+json`. Route-specific members (for example
        `refusalCode`, `transactionId`, `ledgerStatus`, `systemplaneKey`) appear
        flat at the top level beside these.
      additionalProperties: true
      required:
        - type
        - title
        - status
        - detail
        - code
        - requestId
        - service
        - category
      properties:
        type:
          type: string
          description: >-
            A URI that names the error code:
            `https://errors.lerian.studio/v1/<code>`.
          example: https://errors.lerian.studio/v1/BTF-0200
        title:
          type: string
          description: The HTTP status text.
          example: Not Found
        status:
          type: integer
          description: The HTTP status code.
          example: 404
        detail:
          type: string
          description: A human-readable explanation of this occurrence.
          example: transfer not found
        instance:
          type: string
          description: The trace ID of this request, when one was recorded.
          example: 4bf92f3577b34da6a3ce929d0e0e4736
        errors:
          type: array
          description: Each rejected field. Present on field validation errors only.
          items:
            type: object
            properties:
              message:
                type: string
                description: Why the value was rejected.
                example: transferId must be a valid UUID
              location:
                type: string
                description: 'Where the value sits: `body.<field>` or `query.<field>`.'
                example: body.senderAccountId
        code:
          type: string
          description: The stable BTF error code.
          example: BTF-0200
        upstream:
          type: object
          description: >-
            The error that an upstream provider (JD SPB, Midaz) reported. Absent
            unless surfaced.
          properties:
            code:
              type: string
              description: The provider's own error code, verbatim.
              example: AAC90
            message:
              type: string
              description: The provider's own error message, bounded.
              example: Assinatura invalida
        requestId:
          type: string
          description: The request correlation ID. Present even when empty.
          example: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
        service:
          type: string
          description: The system that produced the error.
          example: plugin
        category:
          type: string
          description: The machine-readable error category.
          example: deterministic
    RetainedTEDInMessage:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 018f3a1c-1b2c-7def-8a9b-0c1d2e3f4a5b
        messageSequence:
          type: string
          example: SEQ-42
        messageCode:
          type: string
          example: STR0008R2
        retentionReason:
          type: string
          enum:
            - UNRECOGNIZED_TYPE
            - ACCOUNT_NOT_OWNED
            - ACCOUNT_UNASSIGNED
            - RECIPIENT_NOT_FOUND_RETURN_UNAUTHORIZED
            - CLASSIFICATION_FAILED
            - AMBIGUOUS_CONTROL_ID
            - LEDGER_ROUTE_UNRESOLVED
            - RECIPIENT_AMBIGUOUS_ORGANIZATIONS
            - OWNERSHIP_DECISION_UNAVAILABLE
          example: UNRECOGNIZED_TYPE
        amount:
          type: string
          example: '15000.00'
        retainedAt:
          type: string
          format: date-time
          example: '2026-02-01T15:30:00Z'
        receivedAt:
          type: string
          format: date-time
          example: '2026-02-01T15:29:55Z'
        ageSeconds:
          type: integer
          description: Stops at `closedAt` once the row is closed.
          example: 3600
        contentBytes:
          type: integer
          description: >-
            How much of the message is held, in bytes. Nothing from the message
            is rendered.
          example: 2048
        drained:
          type: boolean
          example: true
        bindingsFingerprint:
          type: string
          nullable: true
          description: >-
            SHA-256 (hex) of the tenant's ledger routing bindings as they stood
            at the last refusal of an open `LEDGER_ROUTE_UNRESOLVED` hold. Two
            holds with different values were refused by different revisions of
            the bindings, and a value that stays the same across an edit means
            the edit has not been checked again yet. Null on every other row,
            and on a hold whose refusal read no bindings.
          example: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
        closedAt:
          type: string
          format: date-time
          description: >-
            `closedAt`, `closedBy`, `outcome`, and `note` are present together
            or not at all, and they are absent on every row of the default
            `open` window.
          example: '2026-02-03T09:12:00Z'
        closedBy:
          type: string
          example: acme/ana.souza
        outcome:
          type: string
          enum:
            - RETURNED
            - CREDITED
            - ABSORBED
          example: RETURNED
        note:
          type: string
          example: >-
            funds wired back to the paying bank under control number
            20260901000042
    PaginationInfo:
      type: object
      required:
        - limit
        - offset
        - returned
        - totalCount
        - hasNextPage
      properties:
        limit:
          type: integer
          description: Maximum number of items requested.
          example: 50
        offset:
          type: integer
          description: Number of items skipped.
          example: 0
        returned:
          type: integer
          description: Number of items returned in this response.
          example: 2
        totalCount:
          type: integer
          minimum: 0
          description: The total number of matching items.
          example: 123
        hasNextPage:
          type: boolean
          description: Whether there are more items beyond the current page.
          example: false
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - service
            - category
            - message
            - requestId
          properties:
            code:
              type: string
              description: >-
                The stable error code. Plugin errors use the `BTF-XXXX` format;
                JD SPB business/auth rejections pass through the raw vendor code
                verbatim (e.g. `AAC90`, `ACE95`, `DVE01`), and transport-level
                JD failures surface the synthetic markers `TRANSPORT` or
                `JD_MISSING_CODE`. Match on this value rather than on the HTTP
                status.
              example: BTF-0010
            service:
              type: string
              description: The service or domain that produced the error.
              example: plugin
            category:
              type: string
              description: Machine-readable error category used for retry decisions.
              enum:
                - deterministic
                - transient
                - rate_limit
                - plugin
              example: deterministic
            message:
              type: string
              description: A human-readable error summary.
              example: >-
                Transfers can only be initiated Monday-Friday between 06:30 and
                17:00 Brasília time
            requestId:
              type: string
              description: The request correlation ID. Present even when empty.
              example: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
            fields:
              type: object
              additionalProperties: true
              description: >-
                Structured validation or retry metadata when available.
                Field-level, header, path, and query validation details are all
                returned here.
              example:
                currentTime: '2026-02-01T18:30:00-03:00'
                operatingHours: Mon-Fri 06:30-17:00 UTC-3
  responses:
    Unauthorized:
      description: Indicates that the request is missing a valid authentication token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            unauthorized:
              summary: Missing authorization
              value:
                error:
                  code: BTF-0401
                  service: plugin
                  category: deterministic
                  message: Missing or invalid authentication token
                  requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
    Forbidden:
      description: >-
        Indicates that the caller is authenticated but lacks permission for this
        operation, or the tenant is not licensed for this endpoint.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            notLicensed:
              summary: Tenant not licensed
              value:
                error:
                  code: BTF-0403
                  service: plugin
                  category: deterministic
                  message: Tenant is not licensed to use this endpoint
                  requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
            permissionDenied:
              summary: Caller lacks permission
              value:
                error:
                  code: BTF-0405
                  service: plugin
                  category: deterministic
                  message: Caller lacks permission for this resource
                  requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
    RateLimitExceeded:
      description: >-
        Indicates that the rate limit has been exceeded. Retry after the number
        of seconds specified in the Retry-After header.
      headers:
        Retry-After:
          description: Seconds until rate limit resets
          schema:
            type: integer
            example: 60
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            rateLimitExceeded:
              summary: Too many requests
              value:
                error:
                  code: BTF-0429
                  service: plugin
                  category: rate_limit
                  message: >-
                    Too many requests. Retry after the interval indicated by the
                    `Retry-After` header.
                  requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
              description: >
                Rate-limit responses use the dedicated `BTF-0429` code with the
                `rate_limit` category. Clients should back off using the HTTP
                status `429` and the `Retry-After` header.
    InternalServerError:
      description: Indicates that an unexpected internal error occurred.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            internalError:
              summary: Internal error
              value:
                error:
                  code: BTF-9000
                  service: plugin
                  category: plugin
                  message: Unexpected error while processing the request
                  requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        JWT Bearer token authentication. The tenantId is derived from the bearer
        token or authenticated request context and is not supplied through
        X-Organization-Id.
    OAuth2ClientCredentials:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: /v1/login/oauth/access_token
          scopes:
            api: TED transfer API access
    OAuth2Password:
      type: oauth2
      flows:
        password:
          tokenUrl: /v1/login/oauth/access_token
          scopes:
            api: TED transfer API access

````