> ## 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 /en/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: 3.2.0
servers:
  - url: https://api.example.com
    description: >-
      Replace the example host with the URL provided during environment
      onboarding.
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
  responses:
    BadRequest:
      description: Indicates that the request contains invalid input.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDocument'
          examples:
            invalidInput:
              summary: Validation error
              value:
                type: https://errors.lerian.studio/v1/BTF-0001
                title: Bad Request
                status: 400
                detail: invalid request body
                code: BTF-0001
                category: deterministic
                requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
                service: plugin
    Unauthorized:
      description: Indicates that the request is missing a valid authentication token.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDocument'
          examples:
            unauthorized:
              summary: Missing authorization
              value:
                type: https://errors.lerian.studio/v1/BTF-0401
                title: Unauthorized
                status: 401
                detail: Missing Token
                code: BTF-0401
                category: plugin
                requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
                service: plugin
    Forbidden:
      description: >-
        Indicates that the caller is authenticated but lacks permission for this
        operation.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDocument'
          examples:
            permissionDenied:
              summary: Caller lacks permission
              value:
                type: https://errors.lerian.studio/v1/BTF-0405
                title: Forbidden
                status: 403
                detail: Forbidden
                code: BTF-0405
                category: plugin
                requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
                service: plugin
    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/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDocument'
          examples:
            rateLimitExceeded:
              summary: Too many requests
              value:
                type: https://errors.lerian.studio/v1/BTF-0429
                title: Too Many Requests
                status: 429
                detail: Rate limit exceeded
                code: BTF-0429
                category: rate_limit
                requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
                service: plugin
              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/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDocument'
          examples:
            internalError:
              summary: Internal error
              value:
                type: https://errors.lerian.studio/v1/BTF-9000
                title: Internal Server Error
                status: 500
                detail: Internal server error
                code: BTF-9000
                category: plugin
                requestId: 6d3e2a68-1f2b-4c3d-9e4f-5a6b7c8d9e0f
                service: plugin
  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

````

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