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

# Check Ledger Routing Readiness

> Use this endpoint to check whether this tenant is ready for ledger-scoped routing. The report lists one line per Midaz organization, ledger, and transfer type:

- Every tuple that has carried a transfer, whatever its outcome. `transferCount` measures traffic, not settlement.
- Every tuple that the chargeback path demands although nothing has transferred on it and no binding addresses it (`transferCount` 0): the inbound tuple that every `TED_OUT` ledger owes for the refund (`derivedFrom: ted_out_refund`), and the outbound tuple that every `TED_IN` ledger owes for the compensation (`derivedFrom: ted_in_compensation`).
- One organization-level line per Midaz organization that the tenant registered to receive inbound TED and that has no inbound binding at any ledger (`derivedFrom: ispb_onboarded_organization`). `ledgerId` is empty, because the recipient account record decides the ledger when the credit arrives. Any inbound line for that organization answers the demand, and the line disappears.

Both chargeback tuples are demanded of a ledger that the configuration only declares, in either mode, as well as of one that has carried traffic. Once a binding answers the demand, the line is reported as a configured scope with no `derivedFrom`, and it is still judged. `ready` is `true` only when every line clears. A declared scope, and the chargeback counterpart of a declared binding, are judged like any other line, because a binding is a promise about money that the operator intends to move, and a route that does not verify on it holds or refuses that ledger's first transfer. An explicit `mode: omit` answers any line, because it posts with the route fields left off, and a chargeback against money that landed unrouted posts back unrouted. The one pairing that it cannot express, a ledger that routes its incoming credits while it declares their compensation unrouted, is refused when the configuration is read and never reaches this report.

The report also lists the bindings that the configuration carries, each with whether a binding covers it and whether the accounting routes it names exist inside that exact scope in Midaz. `legacyPendingInitiations` counts the live initiations still pending from before ledger-scoped routing, which this service answers with 409 (BTF-0112). `readbackBudgetExhausted` is `false` for every configuration that the contract accepts. A `true` value means a service defect: report it instead of retrying. The scopes past the budget then read `unavailable`.

This is a read-only administrative endpoint. It never writes the configuration and never moves money. It does not require the `X-Organization-Id` header. In multi-tenant deployments the report is scoped to the caller's resolved tenant.



## OpenAPI

````yaml /pt/openapi/v3-current/ted.yaml get /v1/transfers/routing/preflight
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/routing/preflight:
    get:
      tags:
        - Transfers API
      summary: Check Ledger Routing Readiness
      description: >-
        Use this endpoint to check whether this tenant is ready for
        ledger-scoped routing. The report lists one line per Midaz organization,
        ledger, and transfer type:


        - Every tuple that has carried a transfer, whatever its outcome.
        `transferCount` measures traffic, not settlement.

        - Every tuple that the chargeback path demands although nothing has
        transferred on it and no binding addresses it (`transferCount` 0): the
        inbound tuple that every `TED_OUT` ledger owes for the refund
        (`derivedFrom: ted_out_refund`), and the outbound tuple that every
        `TED_IN` ledger owes for the compensation (`derivedFrom:
        ted_in_compensation`).

        - One organization-level line per Midaz organization that the tenant
        registered to receive inbound TED and that has no inbound binding at any
        ledger (`derivedFrom: ispb_onboarded_organization`). `ledgerId` is
        empty, because the recipient account record decides the ledger when the
        credit arrives. Any inbound line for that organization answers the
        demand, and the line disappears.


        Both chargeback tuples are demanded of a ledger that the configuration
        only declares, in either mode, as well as of one that has carried
        traffic. Once a binding answers the demand, the line is reported as a
        configured scope with no `derivedFrom`, and it is still judged. `ready`
        is `true` only when every line clears. A declared scope, and the
        chargeback counterpart of a declared binding, are judged like any other
        line, because a binding is a promise about money that the operator
        intends to move, and a route that does not verify on it holds or refuses
        that ledger's first transfer. An explicit `mode: omit` answers any line,
        because it posts with the route fields left off, and a chargeback
        against money that landed unrouted posts back unrouted. The one pairing
        that it cannot express, a ledger that routes its incoming credits while
        it declares their compensation unrouted, is refused when the
        configuration is read and never reaches this report.


        The report also lists the bindings that the configuration carries, each
        with whether a binding covers it and whether the accounting routes it
        names exist inside that exact scope in Midaz. `legacyPendingInitiations`
        counts the live initiations still pending from before ledger-scoped
        routing, which this service answers with 409 (BTF-0112).
        `readbackBudgetExhausted` is `false` for every configuration that the
        contract accepts. A `true` value means a service defect: report it
        instead of retrying. The scopes past the budget then read `unavailable`.


        This is a read-only administrative endpoint. It never writes the
        configuration and never moves money. It does not require the
        `X-Organization-Id` header. In multi-tenant deployments the report is
        scoped to the caller's resolved tenant.
      operationId: getLedgerRoutingReadiness
      responses:
        '200':
          description: Indicates that the readiness report was returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LedgerRoutingReadinessResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '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 report readers are not configured in this deployment.
            BTF-9015: a routing configuration could not be read, either the
            ledger bindings or the organizations registered to receive inbound
            TED; the `systemplaneKey` member names which one. BTF-9007: the scan
            of this tenant's transfers timed out. BTF-9008: the database was
            unreachable.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDocument'
components:
  schemas:
    LedgerRoutingReadinessResponse:
      type: object
      properties:
        ready:
          type: boolean
          description: '`true` only when every line in `scopes` clears.'
          example: false
        documentState:
          type: string
          enum:
            - absent
            - sentinel
            - empty
            - bindings
          example: bindings
        legacyPendingInitiations:
          type: integer
          description: Live initiations still pending from before ledger-scoped routing.
          example: 2
        readbackBudgetExhausted:
          type: boolean
          description: >-
            `false` for every configuration that the contract accepts. `true`
            means a service defect; the scopes past the budget read
            `unavailable`.
          example: false
        scopes:
          type: array
          items:
            $ref: '#/components/schemas/LedgerRoutingReadinessScope'
    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
    LedgerRoutingReadinessScope:
      type: object
      properties:
        organizationId:
          type: string
          format: uuid
          example: 11111111-1111-4111-8111-111111111111
        ledgerId:
          type: string
          description: Empty on an organization-level line; see `derivedFrom`.
          example: 22222222-2222-4222-8222-222222222222
        transferType:
          type: string
          enum:
            - P2P
            - TED_OUT
            - TED_IN
          example: TED_OUT
        transferCount:
          type: integer
          description: >-
            Transfers that this tuple has carried, whatever their outcome. It
            measures traffic, not settlement.
          example: 7
        lastTransferAt:
          type: string
          format: date-time
          example: '2026-09-16T12:30:00Z'
        derivedFrom:
          type: string
          enum:
            - ted_out_refund
            - ted_in_compensation
            - ispb_onboarded_organization
          description: >-
            The demand that produced this line. Absent once a binding answers
            the demand.
          example: ted_out_refund
        covered:
          type: boolean
          description: Whether a binding covers this line.
          example: true
        mode:
          type: string
          enum:
            - routes
            - omit
          description: The binding mode. `omit` posts with the route fields left off.
          example: routes
        routesVerified:
          type: string
          enum:
            - ok
            - missing
            - mismatched
            - unavailable
            - not_applicable
          description: >-
            Whether the accounting routes that the binding names exist inside
            this exact scope in Midaz.
          example: ok
        membership:
          type: string
          enum:
            - verified
            - unverified
            - not_applicable
          example: verified
    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:
    BadRequest:
      description: >-
        Indicates that the request contains invalid input. Check the field
        details for specific validation errors.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalidInput:
              summary: Validation error
              value:
                error:
                  code: BTF-0001
                  service: plugin
                  category: deterministic
                  message: >-
                    The request contains invalid fields. Check the field details
                    below.
                  requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
                  fields:
                    recipientIspb: must be 8 digits
                    amount: must be positive
    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

````