components:
  schemas:
    AuditExportDTO:
      additionalProperties: false
      properties:
        completedAt:
          format: date-time
          type: string
        entityType:
          type: string
        failureReason:
          type: string
        format:
          type: string
        id:
          type: string
        periodFrom:
          format: date-time
          type: string
        periodTo:
          format: date-time
          type: string
        recordCount:
          format: int64
          type: integer
        requestedAt:
          format: date-time
          type: string
        requestedBy:
          type: string
        sha256Hash:
          type: string
        sizeBytes:
          format: int64
          type: integer
        status:
          type: string
      required:
        - id
        - status
        - entityType
        - format
        - periodFrom
        - periodTo
        - requestedBy
        - requestedAt
      type: object
    CancelTransferRequest:
      additionalProperties: false
      properties:
        reason:
          type: string
      type: object
    CheckView:
      additionalProperties: false
      properties:
        checkedAt:
          description: RFC3339 UTC timestamp when the check ran
          examples:
            - "2026-06-03T12:00:00Z"
          type: string
        detail:
          description: Human-readable check outcome detail
          examples:
            - reachable
          type: string
        name:
          description: Health checker name
          examples:
            - bacen_connectivity
          type: string
        status:
          description: "Per-check classification: healthy, warning, or critical"
          examples:
            - healthy
          type: string
      required:
        - name
        - status
        - detail
        - checkedAt
      type: object
    CreateCredentialRequest:
      additionalProperties: false
      properties:
        description:
          type: string
        institutionCode:
          type: string
        operatorId:
          type: string
        password:
          type: string
      required:
        - institutionCode
        - operatorId
        - password
      type: object
    CreateExportRequest:
      additionalProperties: false
      properties:
        entityType:
          description: Audit entity to export (credential_access | transfer_history)
          examples:
            - credential_access
          type: string
        format:
          description: Export format (CSV | JSON_GZIP); defaults to CSV
          examples:
            - CSV
          type: string
        periodFrom:
          description: Inclusive lower bound of the export window (RFC3339)
          examples:
            - "2026-01-01T00:00:00-03:00"
          format: date-time
          type: string
        periodTo:
          description: Inclusive upper bound of the export window (RFC3339)
          examples:
            - "2026-01-31T23:59:59.999999-03:00"
          format: date-time
          type: string
      required:
        - entityType
        - periodFrom
        - periodTo
      type: object
    CreateInboundSourceConfigRequest:
      additionalProperties: false
      properties:
        bacenSystemCode:
          type: string
        bacenSystemFilterCode:
          type: string
        credentialId:
          type: string
        displayName:
          type: string
        intervalSeconds:
          format: int64
          type: integer
        maxFileSizeBytes:
          format: int64
          type: integer
        retentionDays:
          format: int64
          type: integer
        sourceProduct:
          type: string
        urgencyEnabled:
          type: boolean
      required:
        - sourceProduct
        - displayName
        - credentialId
        - intervalSeconds
        - bacenSystemCode
      type: object
    CreateTransferRequest:
      additionalProperties: false
      properties:
        credentialId:
          type: string
        documentType:
          type: string
        fileName:
          type: string
        fileRef:
          type: string
        institutionCode:
          type: string
        sourceProduct:
          type: string
      required:
        - sourceProduct
        - documentType
        - fileRef
        - fileName
      type: object
    CredentialAccessLogDTO:
      additionalProperties: false
      properties:
        actorId:
          type: string
        actorName:
          type: string
        credentialId:
          type: string
        id:
          type: string
        operation:
          type: string
        payload:
          additionalProperties: {}
          type: object
        performedAt:
          format: date-time
          type: string
        result:
          type: string
        sourceIp:
          type: string
      required:
        - id
        - credentialId
        - operation
        - actorId
        - actorName
        - performedAt
        - result
        - payload
      type: object
    CredentialListResponse:
      additionalProperties: false
      properties:
        items:
          items:
            $ref: "#/components/schemas/CredentialView"
          type:
            - array
            - "null"
        pageNumber:
          format: int64
          type: integer
        pageSize:
          format: int64
          type: integer
        totalCount:
          format: int64
          type: integer
      required:
        - items
        - totalCount
        - pageNumber
        - pageSize
      type: object
    CredentialView:
      additionalProperties: false
      properties:
        asOf:
          format: date-time
          type: string
        createdAt:
          format: date-time
          type: string
        daysRemaining:
          format: int64
          type: integer
        description:
          type: string
        expiryStatus:
          type: string
        id:
          type: string
        institutionCode:
          type: string
        lastExpiryCheckedAt:
          format: date-time
          type: string
        lastRotatedAt:
          format: date-time
          type: string
        lastTestResult:
          type: string
        lastTestedAt:
          format: date-time
          type: string
        operatorId:
          type: string
        passwordExpiresAt:
          format: date-time
          type: string
        status:
          type: string
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - institutionCode
        - operatorId
        - status
        - createdAt
        - updatedAt
      type: object
    CurrentPasswordRequest:
      additionalProperties: false
      properties:
        password:
          type: string
      required:
        - password
      type: object
    CurrentPasswordView:
      additionalProperties: false
      properties:
        acceptedAt:
          format: date-time
          type: string
        credentialId:
          type: string
      required:
        - credentialId
        - acceptedAt
      type: object
    Detail:
      additionalProperties: true
      properties:
        code:
          description: "Stable, machine-readable domain error code scoped to the emitting service (format: <SERVICE>-NNNN)."
          type: string
        detail:
          description: A human-readable explanation specific to this occurrence of the problem.
          examples:
            - Property foo is required but is missing.
          type: string
        errors:
          description: Optional list of individual error details
          items:
            $ref: "#/components/schemas/ErrorDetail"
          type:
            - array
            - "null"
        instance:
          description: A URI reference that identifies the specific occurrence of the problem.
          examples:
            - https://example.com/error-log/abc123
          format: uri
          type: string
        status:
          description: HTTP status code
          examples:
            - 400
          format: int64
          type: integer
        title:
          description: A short, human-readable summary of the problem type. This value should not change between occurrences of the error.
          examples:
            - Bad Request
          type: string
        type:
          default: about:blank
          description: A URI reference to human-readable documentation for the error.
          examples:
            - https://example.com/errors/example
          format: uri
          type: string
        upstream:
          $ref: "#/components/schemas/Upstream"
          description: "RFC 9457 extension member: the error a proxied third-party provider reported. Absent unless the emitting service explicitly surfaced one."
      type: object
    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
    ErrorResponse:
      additionalProperties: false
      properties:
        code:
          examples:
            - 400
          format: int64
          type: integer
        message:
          examples:
            - context name is required
          type: string
        title:
          examples:
            - invalid_request
          type: string
      required:
        - code
        - title
        - message
      type: object
    InboundSourceConfigListResponse:
      additionalProperties: false
      properties:
        hasMore:
          type: boolean
        items:
          items:
            $ref: "#/components/schemas/InboundSourceConfigView"
          type:
            - array
            - "null"
        nextCursor:
          type: string
      required:
        - items
        - hasMore
      type: object
    InboundSourceConfigView:
      additionalProperties: false
      properties:
        bacenSystemCode:
          type: string
        bacenSystemFilterCode:
          type: string
        createdAt:
          format: date-time
          type: string
        credentialId:
          type: string
        deletedAt:
          format: date-time
          type: string
        displayName:
          type: string
        id:
          type: string
        intervalSeconds:
          format: int64
          type: integer
        isEnabled:
          type: boolean
        maxFileSizeBytes:
          format: int64
          type: integer
        retentionDays:
          format: int64
          type: integer
        sourceProduct:
          type: string
        updatedAt:
          format: date-time
          type: string
        urgencyEnabled:
          type: boolean
      required:
        - id
        - sourceProduct
        - displayName
        - credentialId
        - intervalSeconds
        - bacenSystemCode
        - isEnabled
        - retentionDays
        - maxFileSizeBytes
        - urgencyEnabled
        - createdAt
        - updatedAt
      type: object
    ListResponseAuditExportDTO:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/AuditExportDTO"
          type:
            - array
            - "null"
        nextCursor:
          type: string
      required:
        - data
      type: object
    ListResponseCredentialAccessLogDTO:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/CredentialAccessLogDTO"
          type:
            - array
            - "null"
        nextCursor:
          type: string
      required:
        - data
      type: object
    ListResponseTransferHistoryDTO:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/TransferHistoryDTO"
          type:
            - array
            - "null"
        nextCursor:
          type: string
      required:
        - data
      type: object
    ListTransfersResponse:
      additionalProperties: false
      properties:
        hasMore:
          type: boolean
        items:
          items:
            $ref: "#/components/schemas/TransferView"
          type:
            - array
            - "null"
        nextCursor:
          type: string
        pageSize:
          format: int64
          type: integer
      required:
        - items
        - hasMore
        - pageSize
      type: object
    ReportView:
      additionalProperties: false
      properties:
        checks:
          description: Result of every registered health checker
          items:
            $ref: "#/components/schemas/CheckView"
          type:
            - array
            - "null"
        generatedAt:
          description: RFC3339 UTC timestamp when the report was generated
          examples:
            - "2026-06-03T12:00:00Z"
          type: string
        status:
          description: "Worst-of aggregate status: healthy, warning, or critical"
          examples:
            - healthy
          type: string
      required:
        - status
        - checks
        - generatedAt
      type: object
    RotateCredentialRequest:
      additionalProperties: false
      properties:
        password:
          type: string
      required:
        - password
      type: object
    RotateView:
      additionalProperties: false
      properties:
        credentialId:
          type: string
        rotatedAt:
          format: date-time
          type: string
      required:
        - credentialId
        - rotatedAt
      type: object
    TestConnectivityView:
      additionalProperties: false
      properties:
        bacenStatusCode:
          format: int64
          type: integer
        credentialId:
          type: string
        message:
          type: string
        responseTimeMs:
          format: int64
          type: integer
        result:
          type: string
        testedAt:
          format: date-time
          type: string
      required:
        - credentialId
        - result
        - responseTimeMs
        - message
        - testedAt
      type: object
    TransferHistoryDTO:
      additionalProperties: false
      properties:
        actorId:
          type: string
        actorName:
          type: string
        fromStateCode:
          format: int64
          type: integer
        id:
          type: string
        reason:
          type: string
        toStateCode:
          format: int64
          type: integer
        transferId:
          type: string
        transitionedAt:
          format: date-time
          type: string
        triggeredBy:
          type: string
      required:
        - id
        - transferId
        - fromStateCode
        - toStateCode
        - triggeredBy
        - actorName
        - transitionedAt
      type: object
    TransferView:
      additionalProperties: false
      properties:
        bytesDownloaded:
          format: int64
          type: integer
        bytesUploaded:
          format: int64
          type: integer
        createdAt:
          format: date-time
          type: string
        credentialId:
          type: string
        currentState:
          type: string
        currentStateCode:
          format: int64
          type: integer
        direction:
          type: string
        documentCode:
          description: "BACEN identifier for the same document (6002). Its provenance differs by direction: on an inbound transfer it is OBSERVED — the <CodigoDocumento> BACEN delivered — while on an outbound transfer it is DERIVED from the CURRENT de-para table at read time — it is what that table resolves the mnemonic to today, NOT a persisted record of the identifier that went on the wire. The two coincide while the table is unchanged; if an entry is ever corrected, this field answers the new value for an old transfer. The identifier actually sent is recorded in the log line and, on a BACEN rejection, in the terminal reason. Treat it as an opaque token, not a number: some documents resolve to a non-numeric identifier (ARQTEST resolves to TEST). Omitted entirely when neither source resolves it, which is a valid state for an outbound document type absent from the table — an empty string is never published, because it would be indistinguishable from a genuinely empty code."
          type: string
        documentType:
          description: "Document type in the MNEMONIC vocabulary (ACCS002) whenever it is known. Outbound: always the mnemonic the caller supplied, unchanged. Inbound: the mnemonic BACEN sent in <Arquivo><TipoArquivo>, published only when the de-para table agrees it names the code that arrived with it. ⚠️ Inbound transfers created before this field was recorded — and BACEN's legacy query envelopes, which omit the element — have no mnemonic stored and are NOT backfilled: those rows answer with the numeric code here, the same value they have always returned. Compare against documentCode to tell the two vocabularies apart."
          type: string
        errorCode:
          type: string
        expired:
          type: boolean
        expiresAt:
          format: date-time
          type: string
        fileName:
          type: string
        fileRef:
          type: string
        fileSizeBytes:
          format: int64
          type: integer
        hashMismatchAttempts:
          description: "Inbound only: count of downloads whose SHA-256 did not match BACEN's, driving the Inconsistent terminal. null for outbound transfers."
          format: int64
          type:
            - integer
            - "null"
        heldUntil:
          description: "Outbound upload held because BACEN STA is unavailable, our connection to it is misconfigured, or BACEN refused the credential's password: when the worker attempts it again. A password refused outside a rotation is not tried again on its own: this is then BACEN's 48h upload deadline, when the worker closes the transfer unless an operator retries it first. Only a transfer that carries it accepts POST /v1/transfers/{id}/retry, which brings that attempt to now. Omitted when the upload is not held."
          format: date-time
          type: string
        id:
          type: string
        lastTransitError:
          type: string
        originProtocolNumber:
          type: string
        protocolGeneratedAt:
          format: date-time
          type: string
        protocolNumber:
          type: string
        secondsRemaining:
          format: int64
          type: integer
        sourceProduct:
          type: string
        transmissionAttempts:
          description: "Inbound only: count of non-hash download failures, driving the Canceled / DOWNLOAD_FAILED terminal. null for outbound transfers."
          format: int64
          type:
            - integer
            - "null"
        updatedAt:
          format: date-time
          type: string
        uploadAttempts:
          description: "Count of FAILED outbound transmission attempts that spend the retry budget: the worker cancels the transfer once it reaches the configured budget (5 by default). An attempt held because BACEN STA is unavailable, because our connection to it is misconfigured, or because BACEN refused the credential's password, spends nothing: the transfer waits for its next attempt until BACEN's 48h upload deadline. A manual retry spends nothing. A transfer that succeeded on the first try reports 0. null for inbound transfers, which have no upload leg."
          format: int64
          type:
            - integer
            - "null"
        urgentRequestedAt:
          format: date-time
          type: string
      required:
        - id
        - direction
        - credentialId
        - documentType
        - fileName
        - fileSizeBytes
        - bytesUploaded
        - bytesDownloaded
        - currentState
        - currentStateCode
        - uploadAttempts
        - hashMismatchAttempts
        - transmissionAttempts
        - createdAt
        - updatedAt
        - secondsRemaining
        - expired
      type: object
    TriggerPollView:
      additionalProperties: false
      properties:
        inboundSourceConfigId:
          type: string
        outcome:
          type: string
      required:
        - inboundSourceConfigId
        - outcome
      type: object
    UpdateCredentialRequest:
      additionalProperties: false
      properties:
        description:
          type: string
        operatorId:
          type: string
      type: object
    UpdateInboundSourceConfigRequest:
      additionalProperties: false
      properties:
        bacenSystemCode:
          type: string
        bacenSystemFilterCode:
          type: string
        credentialId:
          type: string
        displayName:
          type: string
        intervalSeconds:
          format: int64
          type: integer
        isEnabled:
          type: boolean
        maxFileSizeBytes:
          format: int64
          type: integer
        retentionDays:
          format: int64
          type: integer
        sourceProduct:
          type: string
        urgencyEnabled:
          type: boolean
      type: object
    UpdateView:
      additionalProperties: false
      properties:
        credentialId:
          type: string
        updatedAt:
          format: date-time
          type: string
      required:
        - credentialId
        - updatedAt
      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: API for Lerian STA — the participant-side rail that connects the institution to Banco Central do Brasil's STA (Sistema de Transferencia de Arquivos) file-exchange system. It covers outbound and inbound file transfers, BACEN credential management, and inbound source polling configuration.
  license:
    name: Lerian Studio General License
  title: Lerian STA API
  version: v1.3.0
openapi: 3.1.0
paths:
  /v1/audit/credential-access-logs:
    get:
      description: "Returns the credential access-log entries in keyset order (performedAt DESC). Optional filters: credentialId, actorId, operation, and an inclusive from / inclusive to RFC3339 window. Hash-chain fields are never projected."
      operationId: listCredentialAccessLogs
      parameters:
        - description: Opaque keyset pagination cursor from a prior response
          explode: false
          in: query
          name: cursor
          schema:
            description: Opaque keyset pagination cursor from a prior response
            type: string
        - description: Page size; clamped to [1,100] by the service (default 25)
          explode: false
          in: query
          name: limit
          schema:
            description: Page size; clamped to [1,100] by the service (default 25)
            examples:
              - 25
            format: int64
            type: integer
        - description: Filter by credential UUID
          explode: false
          in: query
          name: credentialId
          schema:
            description: Filter by credential UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
        - description: Filter by actor id
          explode: false
          in: query
          name: actorId
          schema:
            description: Filter by actor id
            type: string
        - description: Filter by operation label
          explode: false
          in: query
          name: operation
          schema:
            description: Filter by operation label
            examples:
              - READ
            type: string
        - description: Inclusive lower bound (RFC3339)
          explode: false
          in: query
          name: from
          schema:
            description: Inclusive lower bound (RFC3339)
            examples:
              - "2026-01-01T00:00:00Z"
            type: string
        - description: Inclusive upper bound (RFC3339)
          explode: false
          in: query
          name: to
          schema:
            description: Inclusive upper bound (RFC3339)
            examples:
              - "2026-02-01T00:00:00Z"
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListResponseCredentialAccessLogDTO"
          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 credential access logs
      tags:
        - audit
      x-mint:
        href: /en/reference/rails/sta/get-audit-credential-access-logs
  /v1/audit/credential-access-logs/{id}:
    get:
      description: Returns the credential access-log entry identified by {id}.
      operationId: getCredentialAccessLog
      parameters:
        - description: Credential access log UUID
          in: path
          name: id
          required: true
          schema:
            description: Credential access log UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CredentialAccessLogDTO"
          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: Read a credential access log entry
      tags:
        - audit
      x-mint:
        href: /en/reference/rails/sta/get-audit-credential-access-logs-id
  /v1/audit/exports:
    get:
      description: Returns the audit-export journal in keyset order (requestedAt DESC). No download URL is embedded; fetch GET /v1/audit/exports/{id}/download to stream a READY export.
      operationId: listAuditExports
      parameters:
        - description: Opaque keyset pagination cursor from a prior response
          explode: false
          in: query
          name: cursor
          schema:
            description: Opaque keyset pagination cursor from a prior response
            type: string
        - description: Page size; clamped to [1,100] by the service (default 25)
          explode: false
          in: query
          name: limit
          schema:
            description: Page size; clamped to [1,100] by the service (default 25)
            examples:
              - 25
            format: int64
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListResponseAuditExportDTO"
          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 audit exports
      tags:
        - audit
      x-mint:
        href: /en/reference/rails/sta/get-audit-exports
    post:
      description: Enqueues an asynchronous audit export (status GENERATING) for the given entity type, format, and RFC3339 window. The date range is capped at 365 days; a second concurrent export for the same entity type returns 409. The export generator worker materializes the object.
      operationId: createAuditExport
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateExportRequest"
              description: Audit export creation payload
        required: true
      responses:
        "202":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuditExportDTO"
          description: Accepted
        "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: Create an audit export
      tags:
        - audit
      x-mint:
        href: /en/reference/rails/sta/post-audit-exports
  /v1/audit/exports/{id}:
    get:
      description: Returns the audit export identified by {id}. A READY export whose underlying object has been removed is reported as EXPIRED.
      operationId: getAuditExport
      parameters:
        - description: Audit export UUID
          in: path
          name: id
          required: true
          schema:
            description: Audit export UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuditExportDTO"
          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: Read an audit export
      tags:
        - audit
      x-mint:
        href: /en/reference/rails/sta/get-audit-exports-id
  /v1/audit/exports/{id}/download:
    get:
      description: Streams the READY export object as an attachment (Content-Disposition), proxied through the service so the download stays behind the audit auth chain and works when object storage is only reachable in-cluster. Returns 409 when the export is not READY and 503 when downloads are not configured.
      operationId: downloadAuditExport
      parameters:
        - description: Audit export UUID
          in: path
          name: id
          required: true
          schema:
            description: Audit export UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/gzip:
              schema:
                contentMediaType: application/octet-stream
                format: binary
                type: string
            application/octet-stream:
              schema:
                contentMediaType: application/octet-stream
                format: binary
                type: string
            text/csv:
              schema:
                contentMediaType: application/octet-stream
                format: binary
                type: string
          description: The export object as a streamed attachment.
        "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: Download an audit export object
      tags:
        - audit
      x-mint:
        href: /en/reference/rails/sta/get-audit-exports-id-download
  /v1/audit/transfer-history:
    get:
      description: "Returns the transfer state-transition history in keyset order (transitionedAt DESC). Optional filters: transferId, actorId, triggeredBy, and an inclusive from / inclusive to RFC3339 window. Hash-chain fields are never projected."
      operationId: listTransferHistory
      parameters:
        - description: Opaque keyset pagination cursor from a prior response
          explode: false
          in: query
          name: cursor
          schema:
            description: Opaque keyset pagination cursor from a prior response
            type: string
        - description: Page size; clamped to [1,100] by the service (default 25)
          explode: false
          in: query
          name: limit
          schema:
            description: Page size; clamped to [1,100] by the service (default 25)
            examples:
              - 25
            format: int64
            type: integer
        - description: Filter by transfer UUID
          explode: false
          in: query
          name: transferId
          schema:
            description: Filter by transfer UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
        - description: Filter by actor id
          explode: false
          in: query
          name: actorId
          schema:
            description: Filter by actor id
            type: string
        - description: Filter by trigger source
          explode: false
          in: query
          name: triggeredBy
          schema:
            description: Filter by trigger source
            examples:
              - SYSTEM
            type: string
        - description: Inclusive lower bound (RFC3339)
          explode: false
          in: query
          name: from
          schema:
            description: Inclusive lower bound (RFC3339)
            examples:
              - "2026-01-01T00:00:00Z"
            type: string
        - description: Inclusive upper bound (RFC3339)
          explode: false
          in: query
          name: to
          schema:
            description: Inclusive upper bound (RFC3339)
            examples:
              - "2026-02-01T00:00:00Z"
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListResponseTransferHistoryDTO"
          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 transfer history
      tags:
        - audit
      x-mint:
        href: /en/reference/rails/sta/get-audit-transfer-history
  /v1/audit/transfer-history/{id}:
    get:
      description: Returns the transfer state-transition entry identified by {id}.
      operationId: getTransferHistoryEntry
      parameters:
        - description: Transfer history entry UUID
          in: path
          name: id
          required: true
          schema:
            description: Transfer history entry UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransferHistoryDTO"
          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: Read a transfer history entry
      tags:
        - audit
      x-mint:
        href: /en/reference/rails/sta/get-audit-transfer-history-id
  /v1/credentials:
    get:
      description: Lists credentials with page-based pagination. The encrypted password is never returned. Pagination defaults are clamped by the service.
      operationId: listCredentials
      parameters:
        - description: 1-based page number; clamped by the service
          explode: false
          in: query
          name: page
          schema:
            description: 1-based page number; clamped by the service
            examples:
              - 1
            format: int64
            type: integer
        - description: Page size; clamped by the service
          explode: false
          in: query
          name: pageSize
          schema:
            description: Page size; clamped by the service
            examples:
              - 20
            format: int64
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CredentialListResponse"
          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 credentials
      tags:
        - credentials
      x-mint:
        href: /en/reference/rails/sta/get-credentials
    post:
      description: Provisions a new credential, encrypts the plaintext password with the current master key, and emits credential.created via the outbox in the same transaction.
      operationId: createCredential
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateCredentialRequest"
              description: Credential creation payload
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CredentialView"
          description: Created
        "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: Create a credential
      tags:
        - credentials
      x-mint:
        href: /en/reference/rails/sta/post-credentials
  /v1/credentials/{id}:
    delete:
      description: Soft-deletes the credential by setting status=revoked. LOCAL only — BACEN is never contacted. The row is retained for audit but hidden from list/get; the freed institution code can be re-created. Emits credential.revoked via the outbox in one tx.
      operationId: deleteCredential
      parameters:
        - description: Credential UUID
          in: path
          name: id
          required: true
          schema:
            description: Credential UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "204":
          description: No Content
        "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: Revoke a credential (LOCAL-only soft-delete)
      tags:
        - credentials
      x-mint:
        href: /en/reference/rails/sta/delete-credentials-id
    get:
      description: Returns the credential metadata for the supplied id. The encrypted password is never returned. Emits credential.accessed via the outbox on every successful read.
      operationId: getCredential
      parameters:
        - description: Credential UUID
          in: path
          name: id
          required: true
          schema:
            description: Credential UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CredentialView"
          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: Read a credential
      tags:
        - credentials
      x-mint:
        href: /en/reference/rails/sta/get-credentials-id
    patch:
      description: "Corrects operatorId and description only. A password change is NOT accepted here — use POST /v1/credentials/{id}/rotate. PATCH semantics: only present fields change. Emits credential.updated via the outbox in one tx."
      operationId: updateCredential
      parameters:
        - description: Credential UUID
          in: path
          name: id
          required: true
          schema:
            description: Credential UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateCredentialRequest"
              description: Partial credential update payload
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UpdateView"
          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: Update a credential (LOCAL-only)
      tags:
        - credentials
      x-mint:
        href: /en/reference/rails/sta/patch-credentials-id
  /v1/credentials/{id}/current-password:
    put:
      description: "Only for a credential whose password BACEN refused (409 otherwise). Logs in to BACEN STA once with the entered password, never the stored one: accepted, the password is stored, the credential is active again and its held filings go out at once; refused (422) or unanswered (503), nothing is stored and the credential stays refused. Each refused login counts toward the operator's Sisbacen lockout."
      operationId: enterCurrentCredentialPassword
      parameters:
        - description: Credential UUID
          in: path
          name: id
          required: true
          schema:
            description: Credential UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CurrentPasswordRequest"
              description: The password BACEN holds now for the credential's operator
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CurrentPasswordView"
          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: Enter the current password of a refused credential
      tags:
        - credentials
      x-mint:
        href: /en/reference/rails/sta/put-credentials-id-current-password
  /v1/credentials/{id}/rotate:
    post:
      description: Accepts a client-chosen new password, encrypts it with the current master key, persists it as pending (Phase 0), calls BACEN's PUT /senhaws/senha on the senha-host (manual §9.1) (Phase 1), and promotes pending -> encrypted (Phase 2).
      operationId: rotateCredentialPassword
      parameters:
        - description: Credential UUID
          in: path
          name: id
          required: true
          schema:
            description: Credential UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RotateCredentialRequest"
              description: Rotation payload carrying the new plaintext password
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RotateView"
          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: Rotate the password for a credential
      tags:
        - credentials
      x-mint:
        href: /en/reference/rails/sta/post-credentials-id-rotate
  /v1/credentials/{id}/test:
    post:
      description: "Runs a BACEN STA connectivity probe for the credential and returns the outcome, latency, and diagnostic message. A credential whose password BACEN refused, or one rotating, answers 409 without a login: each failed login counts toward Sisbacen's lockout."
      operationId: testCredentialConnectivity
      parameters:
        - description: Credential UUID
          in: path
          name: id
          required: true
          schema:
            description: Credential UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TestConnectivityView"
          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: Test BACEN STA connectivity for a credential
      tags:
        - credentials
      x-mint:
        href: /en/reference/rails/sta/post-credentials-id-test
  /v1/health:
    get:
      description: "Runs every registered health checker (BACEN connectivity, credential expiry, worker heartbeat, scheduler leader, rate budget, license state), aggregates them worst-of, and returns the structured report. The HTTP status mirrors the aggregate: healthy=200, warning=207 (Multi-Status), critical=503. A report-source failure returns 503 with an RFC 9457 problem document carrying a stable product code."
      operationId: getHealth
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReportView"
          description: OK
        "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: Aggregate health report
      tags:
        - health
      x-mint:
        href: /en/reference/rails/sta/get-health
  /v1/inbound-source-configs:
    get:
      description: Cursor-paginated listing of inbound source configs. The page size is clamped by the query service (default 20, max 100).
      operationId: listInboundSourceConfigs
      parameters:
        - description: Opaque continuation token from a prior page
          explode: false
          in: query
          name: cursor
          schema:
            description: Opaque continuation token from a prior page
            type: string
        - description: Requested page size; clamped by the query service (default 20, max 100)
          explode: false
          in: query
          name: limit
          schema:
            description: Requested page size; clamped by the query service (default 20, max 100)
            examples:
              - 20
            format: int64
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InboundSourceConfigListResponse"
          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 inbound source configs
      tags:
        - inbound-source-configs
      x-mint:
        href: /en/reference/rails/sta/get-inbound-source-configs
    post:
      description: Provisions an inbound source config. Every config is guarded against the configured inbound discovery reserve before persistence; a violation surfaces 422 POLLING_BUDGET_EXCEEDED.
      operationId: createInboundSourceConfig
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateInboundSourceConfigRequest"
              description: Inbound source config creation payload
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InboundSourceConfigView"
          description: Created
        "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: Create an inbound source config
      tags:
        - inbound-source-configs
      x-mint:
        href: /en/reference/rails/sta/post-inbound-source-configs
  /v1/inbound-source-configs/{id}:
    delete:
      description: Soft-deletes the config, clearing its inbound-reserve contribution.
      operationId: deleteInboundSourceConfig
      parameters:
        - description: Inbound source config UUID
          in: path
          name: id
          required: true
          schema:
            description: Inbound source config UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "204":
          description: No Content
        "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: Delete an inbound source config
      tags:
        - inbound-source-configs
      x-mint:
        href: /en/reference/rails/sta/delete-inbound-source-configs-id
    get:
      description: Returns the inbound source config identified by {id}.
      operationId: getInboundSourceConfig
      parameters:
        - description: Inbound source config UUID
          in: path
          name: id
          required: true
          schema:
            description: Inbound source config UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InboundSourceConfigView"
          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: Read an inbound source config
      tags:
        - inbound-source-configs
      x-mint:
        href: /en/reference/rails/sta/get-inbound-source-configs-id
    patch:
      description: Partial update. Re-enabling a config, changing its intervalSeconds, or moving it to a different credential re-validates the configured inbound discovery reserve (422 on violation).
      operationId: updateInboundSourceConfig
      parameters:
        - description: Inbound source config UUID
          in: path
          name: id
          required: true
          schema:
            description: Inbound source config UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateInboundSourceConfigRequest"
              description: Partial inbound source config update payload
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InboundSourceConfigView"
          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: Update an inbound source config
      tags:
        - inbound-source-configs
      x-mint:
        href: /en/reference/rails/sta/patch-inbound-source-configs-id
  /v1/inbound-source-configs/{id}/trigger-poll:
    post:
      description: "Dispatches a manual inbound poll for the inbound source config. Requires an X-Idempotency header, one per trigger: a repeat with the same key within the 7-day retention replays the first outcome (X-Idempotency-Replayed: true) without dispatching again. Documented status is 202 Accepted; the runtime status is dynamic per outcome (200/409/503)."
      operationId: triggerInboundSourceConfigPoll
      parameters:
        - description: Inbound source config UUID
          in: path
          name: id
          required: true
          schema:
            description: Inbound source config UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
        - description: Idempotency key, one per trigger (max 256 bytes). A repeat with the same key replays the original outcome without dispatching again.
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, one per trigger (max 256 bytes). A repeat with the same key replays the original outcome without dispatching again.
            type: string
      responses:
        "202":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TriggerPollView"
          description: Accepted
          headers:
            X-Idempotency-Fenced:
              schema:
                description: true when a lost idempotency receipt left this answer standing and the key is fenced against any resend; false when it is not fenced
                type: string
            X-Idempotency-Replayed:
              schema:
                description: true when the response is a replay of the first request with this X-Idempotency key
                type: string
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: "Conflict. The idempotency middleware answers it in application/json with title IDEMPOTENCY_CONFLICT while a request with this X-Idempotency key is in flight (X-Idempotency-Replayed: true); retry once it settles."
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: "Unprocessable Entity. application/problem+json is request validation; application/json is an idempotency refusal (title IDEMPOTENCY_KEY_REUSE, IDEMPOTENCY_OUTCOME_UNRECORDED, IDEMPOTENCY_STATE_UNRECOGNISED or IDEMPOTENCY_RECORD_UNREADABLE): reconcile, never resend."
        "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: Trigger an inbound poll
      tags:
        - inbound-source-configs
      x-mint:
        href: /en/reference/rails/sta/post-inbound-source-configs-id-trigger-poll
  /v1/inbound/transfers/{id}/mark-urgent:
    post:
      description: Flags an inbound transfer that is AvailableForDownload for immediate download+processing instead of waiting for the next poll cycle.
      operationId: markInboundTransferUrgent
      parameters:
        - description: Inbound transfer UUID
          in: path
          name: id
          required: true
          schema:
            description: Inbound transfer UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransferView"
          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: Mark an inbound transfer for urgent processing
      tags:
        - transfers
      x-mint:
        href: /en/reference/rails/sta/post-inbound-transfers-id-mark-urgent
  /v1/transfers:
    get:
      description: "Lists transfers with cursor-based pagination. Optional filters: state, direction, sourceProduct."
      operationId: listTransfers
      parameters:
        - description: Filter by state name
          explode: false
          in: query
          name: state
          schema:
            description: Filter by state name
            examples:
              - AwaitingUpload
            type: string
        - description: "Filter by direction: outbound | inbound"
          explode: false
          in: query
          name: direction
          schema:
            description: "Filter by direction: outbound | inbound"
            examples:
              - outbound
            type: string
        - description: Filter by source product
          explode: false
          in: query
          name: sourceProduct
          schema:
            description: Filter by source product
            examples:
              - pix
            type: string
        - description: Opaque continuation cursor from a prior page
          explode: false
          in: query
          name: cursor
          schema:
            description: Opaque continuation cursor from a prior page
            type: string
        - description: Requested page size; clamped to 1..100 by the query service (default 20)
          explode: false
          in: query
          name: pageSize
          schema:
            description: Requested page size; clamped to 1..100 by the query service (default 20)
            examples:
              - 20
            format: int64
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListTransfersResponse"
          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 transfers
      tags:
        - transfers
      x-mint:
        href: /en/reference/rails/sta/get-transfers
    post:
      description: "Creates a new outbound transfer. The worker streams the referenced object to BACEN STA asynchronously. A 5xx frees the X-Idempotency key: resend with the same key, and a transfer the failed request did create is answered (201, X-Idempotency-Replayed: true) instead of created twice. A receipt lost after the create ran answers the create's own result with X-Idempotency-Fenced (true: every same-key resend is then refused 422 IDEMPOTENCY_OUTCOME_UNRECORDED for the key's 7 days; false: the key is not fenced, and a same-key resend is answered from the transfer row). A 503 STA-0008 means nothing ran: retry with the same key."
      operationId: createTransfer
      parameters:
        - description: Idempotency key, one per submission (max 256 bytes). A repeat with the same key and the same parsed request (member order and whitespace do not count) replays the original outcome; the same key with another request is refused 422.
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, one per submission (max 256 bytes). A repeat with the same key and the same parsed request (member order and whitespace do not count) replays the original outcome; the same key with another request is refused 422.
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateTransferRequest"
              description: Outbound transfer creation payload
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransferView"
          description: Created
          headers:
            X-Idempotency-Fenced:
              schema:
                description: true when a lost idempotency receipt left the create's own answer standing and the key is fenced against any resend; false when it is not fenced
                type: string
            X-Idempotency-Replayed:
              schema:
                description: true when the response is a replay of the first request with this X-Idempotency key
                type: string
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: "Conflict. The idempotency middleware answers it in application/json with title IDEMPOTENCY_CONFLICT while a request with this X-Idempotency key is in flight (X-Idempotency-Replayed: true); retry once it settles."
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: "Unprocessable Entity. application/problem+json is request validation; application/json is an idempotency refusal (title IDEMPOTENCY_KEY_REUSE, IDEMPOTENCY_OUTCOME_UNRECORDED, IDEMPOTENCY_STATE_UNRECOGNISED or IDEMPOTENCY_RECORD_UNREADABLE): reconcile, never resend."
        "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: Create outbound transfer
      tags:
        - transfers
      x-mint:
        href: /en/reference/rails/sta/post-transfers
  /v1/transfers/{id}:
    get:
      description: Returns the transfer aggregate for the supplied id.
      operationId: getTransfer
      parameters:
        - description: Transfer UUID
          in: path
          name: id
          required: true
          schema:
            description: Transfer UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransferView"
          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: Read a transfer
      tags:
        - transfers
      x-mint:
        href: /en/reference/rails/sta/get-transfers-id
  /v1/transfers/{id}/cancel:
    post:
      description: Flips the transfer to Canceled when its current state is in the cancelable set.
      operationId: cancelTransfer
      parameters:
        - description: Transfer UUID
          in: path
          name: id
          required: true
          schema:
            description: Transfer UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CancelTransferRequest"
              description: Optional cancel reason payload
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransferView"
          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: Cancel a non-terminal transfer
      tags:
        - transfers
      x-mint:
        href: /en/reference/rails/sta/post-transfers-id-cancel
  /v1/transfers/{id}/retry:
    post:
      description: "Brings forward the next attempt of an outbound upload held because BACEN STA is unavailable, our connection to it is misconfigured, or BACEN refused the credential's password: the transfer whose view carries heldUntil. It spends nothing of the attempt budget and keeps the error that made the transfer hold. Any other transfer answers 409: the worker already retries a failed upload, or a held one whose attempt is due, on its own, and a file already sent has nothing left to upload. Refused with 409 once BACEN's 48h upload deadline has passed."
      operationId: retryTransfer
      parameters:
        - description: Transfer UUID
          in: path
          name: id
          required: true
          schema:
            description: Transfer UUID
            examples:
              - 018f3b2a-0c1d-7a2b-9e4f-1a2b3c4d5e6f
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransferView"
          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: Retry a held outbound transfer
      tags:
        - transfers
      x-mint:
        href: /en/reference/rails/sta/post-transfers-id-retry
security:
  - BearerAuth: []
servers:
  - url: https://api.example.com
    description: Replace the example host with the URL provided during environment onboarding.
