components:
  schemas:
    Detail:
      additionalProperties: false
      properties:
        code:
          description: "Stable, machine-readable domain error code scoped to the emitting service (format: <SERVICE>-NNNN)."
          type: string
        correlationId:
          description: Request-scoped correlation identifier echoing X-Request-ID.
          examples:
            - req-7a3f9c2e
          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."
      required:
        - correlationId
      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
    OperationRoutingDecisionResponse:
      additionalProperties: false
      properties:
        indirectISPB:
          description: ISPB of the indirect participant being routed through the sponsor (8 digits or uppercase letters); empty for direct participants.
          examples:
            - "12345678"
          type: string
        isDirect:
          description: True when the sender connects directly to BACEN; false when routed through a sponsor.
          examples:
            - false
          type: boolean
        quotaConsumed:
          description: Amount in centavos (BRL minor units) consumed from the indirect participant's quota for this operation.
          examples:
            - 15000
          format: int64
          type: integer
        sponsorISPB:
          description: ISPB of the sponsor participant routing the payment (8 digits or uppercase letters); empty for direct participants.
          examples:
            - "87654321"
          type: string
      required:
        - quotaConsumed
        - isDirect
      type: object
    OrchestrateOperationRequest:
      additionalProperties: false
      properties:
        amount:
          description: Transaction amount in centavos (BRL minor units); must be greater than zero.
          examples:
            - 15000
          format: int64
          minimum: 1
          type: integer
        commissionAmount:
          description: Commission amount in centavos (BRL minor units); zero or positive.
          examples:
            - 10
          format: int64
          minimum: 0
          type: integer
        commissionRecipientISPB:
          description: ISPB of the participant receiving the commission (8 digits or uppercase letters); optional.
          examples:
            - "87654321"
          type: string
        endToEndId:
          description: PIX EndToEndID of the transaction, 32 characters, shaped as BACEN's EndToEndIdType (E, then the 8-character participant segment, then YYYYMMDDHHMM, then an 11-character unique tail). The date and minute components are additionally parsed as a real instant, and the participant segment must equal senderISPB, before the operation is accepted.
          examples:
            - E12345678202604281234ABCDE123456
          pattern: ^E[0-9A-Z]{8}[0-9]{12}[a-zA-Z0-9]{11}$
          type: string
        feeAmount:
          description: Fee amount in centavos (BRL minor units); zero or positive.
          examples:
            - 25
          format: int64
          minimum: 0
          type: integer
        feePayerISPB:
          description: ISPB of the participant charged the fee (8 digits or uppercase letters); optional.
          examples:
            - "12345678"
          type: string
        operationId:
          description: "Caller-assigned idempotency/business identifier for the operation. Lerian's own bound, not BACEN's: 128 characters is what the orchestration command enforces and what core_sagas.operation_id stores."
          examples:
            - op-20260428-0001
          maxLength: 128
          minLength: 1
          type: string
        senderISPB:
          description: ISPB of the sending participant, exactly 8 digits or uppercase letters (BACEN ISPBType [0-9A-Z]{8}).
          examples:
            - "12345678"
          pattern: ^[0-9A-Z]{8}$
          type: string
      required:
        - operationId
        - endToEndId
        - senderISPB
        - amount
        - feeAmount
        - commissionAmount
      type: object
    OrchestrateOperationResponse:
      additionalProperties: false
      properties:
        commissionAmount:
          description: Commission amount applied, in centavos (BRL minor units).
          examples:
            - 10
          format: int64
          type: integer
        commissionRecipientISPB:
          description: ISPB of the participant receiving the commission (8 digits or uppercase letters); omitted when no fee attribution applies.
          examples:
            - "87654321"
          type: string
        feeAmount:
          description: Fee amount applied, in centavos (BRL minor units).
          examples:
            - 25
          format: int64
          type: integer
        feeAttributionId:
          description: UUID of the fee attribution record; empty when no fee attribution was created.
          examples:
            - 550e8400-e29b-41d4-a716-446655440000
          type: string
        feePayerISPB:
          description: ISPB of the participant charged the fee (8 digits or uppercase letters); omitted when no fee attribution applies.
          examples:
            - "12345678"
          type: string
        operationId:
          description: Caller-assigned identifier echoed from the request.
          examples:
            - op-20260428-0001
          type: string
        routingDecision:
          $ref: "#/components/schemas/OperationRoutingDecisionResponse"
          description: Routing snapshot showing how the operation was directed through sponsor/indirect participants.
        sagaId:
          description: UUID of the orchestration saga coordinating the operation.
          examples:
            - 550e8400-e29b-41d4-a716-446655440000
          type: string
        sagaStatus:
          description: Current state of the orchestration saga (e.g. COMPLETED).
          examples:
            - COMPLETED
          type: string
        settlementId:
          description: UUID of the settlement created for this operation.
          examples:
            - 550e8400-e29b-41d4-a716-446655440000
          type: string
        settlementStatus:
          description: Current state of the settlement (e.g. PENDING).
          examples:
            - PENDING
          type: string
      required:
        - sagaId
        - operationId
        - sagaStatus
        - settlementId
        - settlementStatus
        - feeAttributionId
        - routingDecision
        - feeAmount
        - commissionAmount
      type: object
    ParticipantConfigDTO:
      additionalProperties: false
      properties:
        quotaDailyLimit:
          description: Maximum total routed amount per day in centavos (BRL minor units).
          examples:
            - 1000000
          format: int64
          type: integer
        quotaTransactionLimit:
          description: Maximum amount per single transaction in centavos (BRL minor units).
          examples:
            - 50000
          format: int64
          type: integer
        routingPolicy:
          description: Payment routing policy for the indirect participant; currently only DEFAULT (route through sponsor with quota enforcement) is accepted.
          examples:
            - DEFAULT
          type: string
      required:
        - quotaDailyLimit
        - quotaTransactionLimit
        - routingPolicy
      type: object
    ParticipantListResponse:
      additionalProperties: false
      properties:
        correlationId:
          description: Request-scoped correlation identifier echoing X-Request-ID, for pivoting from response to trace.
          type: string
        items:
          description: Participants for the requested limit/offset window.
          items:
            $ref: "#/components/schemas/ParticipantResponse"
          type: array
        limit:
          description: Effective page size applied to this response.
          format: int64
          type: integer
        offset:
          description: Zero-based offset of the first item in this page.
          format: int64
          type: integer
      required:
        - items
        - limit
        - offset
      type: object
    ParticipantResponse:
      additionalProperties: false
      properties:
        config:
          $ref: "#/components/schemas/ParticipantConfigDTO"
          description: Quota and routing configuration; present only for indirect participants.
        contactEmail:
          description: Registered regulator-facing e-mail; travels on every MED 2.0 funds recovery opened for this participant.
          examples:
            - med@bancoexemplo.com.br
          type: string
        contactPhone:
          description: Registered regulator-facing phone; travels on every MED 2.0 funds recovery opened for this participant.
          examples:
            - "+5511999998888"
          type: string
        createdAt:
          description: UTC timestamp when the participant was created, RFC 3339 format.
          examples:
            - "2025-03-07T14:30:00Z"
          type: string
        id:
          description: Server-assigned UUID of the participant.
          examples:
            - 550e8400-e29b-41d4-a716-446655440000
          type: string
        ispb:
          description: ISPB of the participant, exactly 8 digits or uppercase letters.
          examples:
            - "12345678"
          type: string
        name:
          description: Legal name of the participant institution.
          examples:
            - Banco Exemplo S.A.
          type: string
        sponsorISPB:
          description: ISPB of the sponsoring participant (8 digits or uppercase letters); present only for INDIRECT participants.
          examples:
            - ""
          type: string
        status:
          description: "Lifecycle state of the participant: ACTIVE, SUSPENDED, OFFBOARDED, PENDING (indirect reda.014 in flight), REGISTRATION_REJECTED (reda.016 REJT), or OFFBOARD_PENDING (reda.031 in flight)."
          examples:
            - ACTIVE
          type: string
        type:
          description: "Connection type: DIRECT (connects directly to BACEN) or INDIRECT (routes through a sponsor)."
          examples:
            - DIRECT
          type: string
        updatedAt:
          description: UTC timestamp of the last update to the participant, RFC 3339 format.
          examples:
            - "2025-03-07T14:30:00Z"
          type: string
      required:
        - id
        - ispb
        - name
        - type
        - status
        - contactEmail
        - contactPhone
        - createdAt
        - updatedAt
      type: object
    RegisterDirectParticipantRequest:
      additionalProperties: false
      properties:
        contactEmail:
          description: "Lower-case e-mail BACEN uses to reach this participant about a funds-recovery case (DICT 2.12.1 Email pattern). The address must be lower-case: an upper-case one is refused, never rewritten. The service checks the format, not the published schema, so a refusal never echoes the submitted value back."
          examples:
            - med@bancoexemplo.com.br
          type: string
        contactPhone:
          description: "E.164 phone BACEN uses to reach this participant about a funds-recovery case (DICT 2.12.1 Phone pattern: +, then 2 to 15 digits). The service checks the format, not the published schema, so a refusal never echoes the submitted value back."
          examples:
            - "+5511999998888"
          type: string
        ispb:
          description: ISPB of the institution this rail operates as, exactly 8 digits or uppercase letters.
          examples:
            - "12345678"
          pattern: ^[0-9A-Z]{8}$
          type: string
        name:
          description: Legal name of the institution. The 256-character bound is Lerian's own — it is what participants.name stores — not a BACEN limit.
          examples:
            - Banco Exemplo S.A.
          maxLength: 256
          minLength: 1
          type: string
      required:
        - ispb
        - name
        - contactEmail
        - contactPhone
      type: object
    RegisterParticipantRequest:
      additionalProperties: false
      properties:
        cnpj:
          description: 14-char CNPJ (alphanumeric per PICnpj [0-9A-Z]{12}[0-9]{2}) of the indirect participant; required for INDIRECT registration (rides the reda.014 MktSpcfcAttr CNPJIDRT).
          examples:
            - "12345678000199"
          maxLength: 14
          minLength: 14
          pattern: ^[0-9A-Z]{12}[0-9]{2}$
          type: string
        config:
          $ref: "#/components/schemas/ParticipantConfigDTO"
          description: Quota and routing configuration; supplied only for indirect participants.
        contactEmail:
          description: "Lower-case e-mail BACEN uses to reach this participant about a funds-recovery case (DICT 2.12.1 Email pattern). The address must be lower-case: an upper-case one is refused, never rewritten. The service checks the format, not the published schema, so a refusal never echoes the submitted value back."
          examples:
            - med@bancoexemplo.com.br
          type: string
        contactPhone:
          description: "E.164 phone BACEN uses to reach this participant about a funds-recovery case (DICT 2.12.1 Phone pattern: +, then 2 to 15 digits). The service checks the format, not the published schema, so a refusal never echoes the submitted value back."
          examples:
            - "+5511999998888"
          type: string
        ispb:
          description: ISPB of the participant, exactly 8 digits or uppercase letters.
          examples:
            - "12345678"
          pattern: ^[0-9A-Z]{8}$
          type: string
        name:
          description: Legal name of the participant institution. The 256-character bound is Lerian's own — it is what participants.name stores — not a BACEN limit.
          examples:
            - Banco Exemplo S.A.
          maxLength: 256
          minLength: 1
          type: string
        sponsorISPB:
          description: ISPB of the sponsoring participant (8 digits or uppercase letters); required for INDIRECT.
          examples:
            - '87654321'
          pattern: ^[0-9A-Z]{8}$
          type: string
        type:
          description: Connection type; must be INDIRECT. A direct participant is registered on the admin route POST /api/v1/core/participants/direct.
          enum:
            - INDIRECT
          examples:
            - INDIRECT
          type: string
      required:
        - ispb
        - name
        - type
        - sponsorISPB
        - contactEmail
        - contactPhone
        - cnpj
      type: object
    ResolveRoutingRequest:
      additionalProperties: false
      properties:
        amount:
          description: Transaction amount in centavos (BRL minor units) to validate against quota; must be greater than zero.
          examples:
            - 15000
          format: int64
          minimum: 1
          type: integer
        senderISPB:
          description: ISPB of the sending participant whose routing is being resolved, exactly 8 digits or uppercase letters.
          examples:
            - "12345678"
          pattern: ^[0-9A-Z]{8}$
          type: string
      required:
        - senderISPB
        - amount
      type: object
    RoutingDecisionResponse:
      additionalProperties: false
      properties:
        indirectISPB:
          description: ISPB of the indirect participant being routed through the sponsor (8 digits or uppercase letters); empty for direct participants.
          examples:
            - "12345678"
          type: string
        isDirect:
          description: True when the sender connects directly to BACEN; false when routed through a sponsor.
          examples:
            - false
          type: boolean
        quotaValidatedAmount:
          description: Amount in centavos (BRL minor units) validated against the indirect participant's quota.
          examples:
            - 15000
          format: int64
          type: integer
        sponsorISPB:
          description: ISPB of the sponsor participant routing the payment (8 digits or uppercase letters); empty for direct participants.
          examples:
            - "87654321"
          type: string
      required:
        - quotaValidatedAmount
        - isDirect
      type: object
    UpdateParticipantContactRequest:
      additionalProperties: false
      properties:
        contactEmail:
          description: "Lower-case e-mail BACEN uses to reach this participant about a funds-recovery case (DICT 2.12.1 Email pattern). Replaces the registered value. The address must be lower-case: an upper-case one is refused, never rewritten. The service checks the format, not the published schema, so a refusal never echoes the submitted value back."
          examples:
            - med@bancoexemplo.com.br
          type: string
        contactPhone:
          description: "E.164 phone BACEN uses to reach this participant about a funds-recovery case (DICT 2.12.1 Phone pattern: +, then 2 to 15 digits). Replaces the registered value. The service checks the format, not the published schema, so a refusal never echoes the submitted value back."
          examples:
            - "+5511999998888"
          type: string
      required:
        - contactEmail
        - contactPhone
      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
info:
  contact:
    email: contact@lerian.studio
    name: Lerian Studio
    url: https://lerian.studio
  description: 'Core service of Lerian SPI: PIX participant lifecycle by ISPB, payment routing resolution, and cross-context Core operation orchestration over the Brazilian Instant Payment System (SPI/Pix).'
  license:
    name: Lerian Studio General License
  title: Lerian SPI — Core API
  version: 1.0.0
openapi: 3.1.0
paths:
  /api/v1/core/operations/:
    post:
      description: Resolves participant routing, consumes quota when indirect, records settlement tracking, attributes fees/commissions, persists saga state, and emits Core domain events.
      operationId: orchestrateOperation
      parameters:
        - description: Idempotency key, max 255 characters
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, max 255 characters
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OrchestrateOperationRequest"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrchestrateOperationResponse"
          description: OK
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Conflict
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Orchestrate Core operation
      tags:
        - Operations
      x-mint:
        href: /pt/reference/rails/spi/core/orchestrate-operation
  /api/v1/core/participants/:
    get:
      description: Returns a paginated list of participants; filterable by sponsor ISPB.
      operationId: listParticipants
      parameters:
        - description: Filter by sponsor ISPB (8 digits or uppercase letters)
          explode: false
          in: query
          name: sponsorISPB
          schema:
            description: Filter by sponsor ISPB (8 digits or uppercase letters)
            type: string
        - description: Page size (default 20, max 100)
          explode: false
          in: query
          name: limit
          schema:
            default: 20
            description: Page size (default 20, max 100)
            format: int64
            maximum: 100
            minimum: 1
            type: integer
        - description: Page offset (default 0)
          explode: false
          in: query
          name: offset
          schema:
            default: 0
            description: Page offset (default 0)
            format: int64
            minimum: 0
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantListResponse"
          description: OK
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: List participants
      tags:
        - Participants
      x-mint:
        href: /pt/reference/rails/spi/core/list-participants
    post:
      description: "Opens a reda.014 (PtyCreReq) asking the SPI to record this rail as the indirect participant's liquidante. The participant is created PENDING and stays there: only the BACEN reda.016 COMP advice makes it ACTIVE, and only an ACTIVE indirect has its arriving Pix settled here. A body naming a DIRECT participant is refused — the rail's own identity is established on the admin route POST /api/v1/core/participants/direct."
      operationId: requestIndirectParticipantRegistration
      parameters:
        - description: Idempotency key, max 255 characters
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, max 255 characters
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RegisterParticipantRequest"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantResponse"
          description: Created
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Conflict
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Request registration of an indirect participant
      tags:
        - Participants
      x-mint:
        href: /pt/reference/rails/spi/core/register-participant
  /api/v1/core/participants/direct:
    post:
      description: "Establishes the institution this rail IS at the SPI: the ACTIVE DIRECT participant that anchors the closed set of participants whose arriving Pix settle here (its own accounts, plus every indirect it is BACEN-confirmed liquidante for). Admin-only, and at most one may be ACTIVE. There is no reda flow for a direct participant — the SPI refuses a reda.014/reda.031 naming one (reda.016 error DIR1) — so nothing external confirms this act and it is not client-callable."
      operationId: registerDirectParticipant
      parameters:
        - description: Idempotency key, max 255 characters
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, max 255 characters
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RegisterDirectParticipantRequest"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantResponse"
          description: Created
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Conflict
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Register the direct participant this rail operates as
      tags:
        - Participants
      x-mint:
        href: /pt/reference/rails/spi/core/register-direct-participant
  /api/v1/core/participants/{ispb}:
    get:
      description: Retrieves a single participant by its ISPB (8 digits or uppercase letters).
      operationId: getParticipant
      parameters:
        - description: ISPB (8 digits or uppercase letters)
          in: path
          name: ispb
          required: true
          schema:
            description: ISPB (8 digits or uppercase letters)
            examples:
              - "12345678"
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantResponse"
          description: OK
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Not Found
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Get participant
      tags:
        - Participants
      x-mint:
        href: /pt/reference/rails/spi/core/get-participant
  /api/v1/core/participants/{ispb}/activate:
    post:
      description: Reactivates a suspended participant.
      operationId: activateParticipant
      parameters:
        - description: Idempotency key, max 255 characters
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, max 255 characters
            type: string
        - description: ISPB (8 digits or uppercase letters)
          in: path
          name: ispb
          required: true
          schema:
            description: ISPB (8 digits or uppercase letters)
            examples:
              - "12345678"
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantResponse"
          description: OK
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Conflict
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Activate participant
      tags:
        - Participants
      x-mint:
        href: /pt/reference/rails/spi/core/activate-participant
  /api/v1/core/participants/{ispb}/contact:
    put:
      description: "Replaces the e-mail and phone BACEN uses to reach this participant about a MED 2.0 funds-recovery case (DICT 2.12.1 ContactInformation). Both elements move together — BACEN requires the pair — and both are validated against the DICT patterns, so a contact this rail would be refused on is refused here instead of on a signed body with a case already half-open. This is registry data: NO reda message carries the contact (the reda.014 envelope is ISPB / IDRT / CNPJIDRT and nothing else), and the funds-recovery flows read the registry fresh at send time, so no re-transmission to BACEN is needed and the change takes effect on the next case opened for this participant. Refused for a participant in a terminal status (OFFBOARDED, REGISTRATION_REJECTED); allowed while a reda.014/reda.031 is in flight, because neither message carries the contact."
      operationId: updateParticipantContact
      parameters:
        - description: Idempotency key, max 255 characters
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, max 255 characters
            type: string
        - description: ISPB (8 digits or uppercase letters)
          in: path
          name: ispb
          required: true
          schema:
            description: ISPB (8 digits or uppercase letters)
            examples:
              - "12345678"
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateParticipantContactRequest"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantResponse"
          description: OK
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Conflict
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Update the participant's MED 2.0 regulator contact
      tags:
        - Participants
      x-mint:
        href: /pt/reference/rails/spi/core/update-participant-contact
  /api/v1/core/participants/{ispb}/offboard:
    post:
      description: "Offboards a participant. A direct participant is OFFBOARDED (terminal) at once. An indirect participant moves to OFFBOARD_PENDING and this rail sends BACEN a reda.031: the reda.016 that answers it makes the indirect OFFBOARDED, or ACTIVE again when BACEN refuses. An indirect already OFFBOARD_PENDING can be offboarded again only once its reda.031 is known not to have reached BACEN; while that reda.031 awaits BACEN's answer the call answers 409."
      operationId: offboardParticipant
      parameters:
        - description: Idempotency key, max 255 characters
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, max 255 characters
            type: string
        - description: ISPB (8 digits or uppercase letters)
          in: path
          name: ispb
          required: true
          schema:
            description: ISPB (8 digits or uppercase letters)
            examples:
              - "12345678"
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantResponse"
          description: OK
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Conflict
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Offboard participant
      tags:
        - Participants
      x-mint:
        href: /pt/reference/rails/spi/core/offboard-participant
  /api/v1/core/participants/{ispb}/suspend:
    post:
      description: Suspends an active participant.
      operationId: suspendParticipant
      parameters:
        - description: Idempotency key, max 255 characters
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, max 255 characters
            type: string
        - description: ISPB (8 digits or uppercase letters)
          in: path
          name: ispb
          required: true
          schema:
            description: ISPB (8 digits or uppercase letters)
            examples:
              - "12345678"
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantResponse"
          description: OK
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Conflict
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Suspend participant
      tags:
        - Participants
      x-mint:
        href: /pt/reference/rails/spi/core/suspend-participant
  /api/v1/core/routing/resolve:
    post:
      description: Resolves the routing path for a payment based on the sender's ISPB and amount.
      operationId: resolveRouting
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ResolveRoutingRequest"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RoutingDecisionResponse"
          description: OK
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Not Found
        "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
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Resolve payment routing
      tags:
        - Routing
      x-mint:
        href: /pt/reference/rails/spi/core/resolve-routing
servers:
  - url: https://api.example.com
    description: Replace the example host with the URL provided during environment onboarding.
tags:
  - description: "PIX participant lifecycle: register, list, retrieve, suspend, activate, and offboard by ISPB."
    name: Participants
  - description: Payment routing resolution across participants.
    name: Routing
  - description: Core operation orchestration across the rail's bounded contexts.
    name: Operations
