{
  "openapi": "3.1.0",
  "info": {
    "title": "CEMI Financial Innovation Lab - Virtual Financial Ecosystem Simulation",
    "version": "0.1.0",
    "description": "A digital twin of the financial ecosystem. Every institution reachable through this gateway is simulated and carries a Lab name; none of them is the entity it is modelled after, none claims its endorsement, and no real institution, person or money is involved. This is NOT an \"ambiente de prueba\" under Art. 83 of the Reglamento de Sistemas de Pago, and a run is never a substitute for the Central Bank's no objection.",
    "contact": {
      "name": "CEMI Financial Innovation Lab",
      "email": "contact@cemi.ai"
    }
  },
  "servers": [
    {
      "url": "http://localhost:8787",
      "description": "local run"
    }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-lab-api-key"
      },
      "firebaseIdToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Firebase ID token"
      }
    },
    "schemas": {
      "Health": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string"
          },
          "simulatedInstant": {
            "type": "string"
          },
          "localTime": {
            "type": "string"
          },
          "clockMode": {
            "type": "string"
          },
          "ruleCatalogue": {
            "type": "string"
          },
          "reportsBackend": {
            "type": "string",
            "enum": [
              "disk",
              "firestore"
            ]
          },
          "auth": {
            "type": "object",
            "properties": {
              "required": {
                "type": "boolean"
              },
              "allowList": {
                "type": "boolean"
              }
            }
          },
          "rules": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "LAB.NOT_AMBIENTE_DE_PRUEBA",
                "LAB.SIMULATOR_CARRIES_LAB_NAME",
                "SIPARD.DIRECT_PARTICIPANT_HAS_CB_ACCOUNT",
                "SIPARD.INTEROPERABILITY",
                "SIPARD.SGPI_MANAGED_BY_CENTRAL_BANK",
                "RECORDS.RETENTION_YEARS",
                "RECORDS.INCLUDES_REJECTED",
                "AML.SCREENING_REQUIRED",
                "LBTR.THIRD_PARTY_CREDIT",
                "LBTR.IRREVOCABLE_ONCE_SETTLED",
                "LBTR.REVOCABLE_WHILE_QUEUED",
                "LBTR.SETTLEMENT_CURRENCY",
                "NET.SETTLES_IN_LBTR",
                "NET.DEFERRED_FINALITY",
                "LBTR.HIGH_VALUE_THRESHOLD",
                "LBTR.PRIORITY_RANGE_PARTICIPANT",
                "LBTR.PRIORITY_DEFAULT",
                "LBTR.PRIORITY_RESERVED_TO_CENTRAL_BANK",
                "LBTR.PRIORITY_RANGE_DVP",
                "LBTR.SETTLEMENT_PRELATION",
                "LBTR.QUEUE_ON_INSUFFICIENT_FUNDS",
                "LBTR.REVOCABLE_UNTIL_SETTLED",
                "LBTR.END_OF_DAY_QUEUE_FLUSH",
                "LBTR.ORDER_STATE",
                "SGPI.FINAL_CREDIT",
                "SGPI.AVAILABILITY",
                "SGPI.MANDATORY_PARTICIPATION",
                "SGPI.NOTIFY_BOTH_PARTIES",
                "SGPI.ALIAS_ADDRESSING",
                "PAI.FINAL_CREDIT",
                "PAI.OPERATING_WINDOW",
                "PAI.DEFERRED_TO_NEXT_BUSINESS_DAY",
                "PAI.FIXED_FEE_ONLY",
                "PAI.NO_DEDUCTION_BY_RECEIVING_BANK",
                "TRANSFER.NO_CHARGE_TO_BENEFICIARY",
                "PAI.FEE_REVERSED_ON_MISSED_DEADLINE",
                "PAI.CLAIM_RESPONSE_OPERATIONAL",
                "PAI.CLAIM_RESPONSE_CLIENT",
                "CLAIM.TYPIFICATION",
                "EPA.BALANCE_CAP",
                "EPA.FUNDING_CAP_30D",
                "CARD.PREPAID_CAP",
                "EPA.NO_INTEREST",
                "EPA.PERMITTED_OPERATION",
                "EPA.ADDITIONAL_CREDENTIALS",
                "QR.PRESENT_AND_READ",
                "INITIATION.NEVER_HOLDS_FUNDS",
                "ACCOUNT.STANDARD_NUMBER",
                "EPA.FUNDING_AVAILABLE_AFTER_SETTLEMENT",
                "EPA.FUNDING_AVAILABLE_AFTER_CHEQUE",
                "EPA.CAP_WINDOW_IS_CALENDAR_DAYS",
                "EPA.FUNDING_OVER_CAP_REJECTED",
                "EPA.NO_OVERDRAFT",
                "EPA.FLOAT_FULLY_BACKED_AT_CENTRAL_BANK",
                "EPA.DAILY_REPORT_TO_CENTRAL_BANK",
                "EPA.CLAIM_RECEPTION_YEARS",
                "EPA.CLAIM_RESPONSE_DAYS",
                "EPA.NO_FEE_FOR_CLAIMS",
                "EPA.FLOAT_ONLY_AT_CENTRAL_BANK",
                "CAPITAL.SYSTEM_ADMINISTRATOR_AND_ACQUIRER",
                "CAPITAL.EPE_SUBACQUIRER_ATM_WALLET",
                "CAPITAL.INITIATION_PROVIDER",
                "SIPA.OPERATING_WINDOW",
                "SIPA.ORIGINATOR_FEE",
                "AGENT.PERMITTED_ACTIVITY",
                "DDC.RETURN_CARRIES_REASON_CODE",
                "DDC.CYCLE_ON_BUSINESS_DAY",
                "DDC.CREDITING_TIME_IS_DECLARED_NOT_FIXED",
                "DDC.CLAIM_RECEPTION_YEARS",
                "ATM.CARDHOLDER_VERIFICATION",
                "ATM.CARDLESS_ORDER_SINGLE_USE",
                "ATM.DEPOSIT_DISCREPANCY_RECORDED",
                "PAI.USD_NO_CORRESPONDENT",
                "PAI.ORIGINATOR_CONVERTS",
                "FX.CONVERSION_RECORDED",
                "AML.TRANSACTION_MONITORING"
              ]
            }
          }
        }
      },
      "CreditTransferInstruction": {
        "type": "object",
        "description": "ISO 20022 pain.001 / pacs.008 JSON projection, plus the Lab routing block.",
        "required": [
          "GrpHdr",
          "CdtTrfTxInf"
        ],
        "properties": {
          "MsgDefIdr": {
            "type": "string",
            "example": "pacs.008.001.12"
          },
          "GrpHdr": {
            "type": "object",
            "properties": {
              "MsgId": {
                "type": "string"
              },
              "CreDtTm": {
                "type": "string"
              },
              "NbOfTxs": {
                "type": "integer"
              },
              "CtrlSum": {
                "type": "number"
              },
              "InitgPty": {
                "type": "object",
                "properties": {
                  "Nm": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "CdtTrfTxInf": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "PmtId": {
                  "type": "object",
                  "properties": {
                    "InstrId": {
                      "type": "string"
                    },
                    "EndToEndId": {
                      "type": "string"
                    }
                  }
                },
                "Amt": {
                  "type": "object",
                  "properties": {
                    "InstdAmt": {
                      "type": "object",
                      "properties": {
                        "Ccy": {
                          "type": "string",
                          "enum": [
                            "DOP",
                            "USD",
                            "EUR"
                          ]
                        },
                        "value": {
                          "type": "number"
                        }
                      }
                    }
                  }
                },
                "ChrgBr": {
                  "type": "string",
                  "enum": [
                    "DEBT",
                    "CRED",
                    "SHAR",
                    "SLEV"
                  ],
                  "description": "CRED is refused: the beneficiary is never charged (Art. 81)"
                },
                "DbtrAcct": {
                  "type": "object"
                },
                "DbtrAgt": {
                  "type": "object"
                },
                "CdtrAcct": {
                  "type": "object",
                  "description": "Ccy carries the beneficiary account's own currency. When it differs from the ordering account's, the originating institution converts and the beneficiary is credited in their own currency.",
                  "properties": {
                    "Id": {
                      "type": "object"
                    },
                    "Ccy": {
                      "type": "string",
                      "enum": [
                        "DOP",
                        "USD",
                        "EUR"
                      ]
                    }
                  }
                },
                "CdtrAgt": {
                  "type": "object"
                },
                "CdtrAlias": {
                  "type": "string",
                  "description": "SGPI alias, resolved by the simulated Central Bank directory"
                },
                "Prty": {
                  "type": "string",
                  "enum": [
                    "HIGH",
                    "NORM"
                  ]
                }
              }
            }
          }
        }
      },
      "AtmWithdrawalRequest": {
        "type": "object",
        "required": [
          "terminalId",
          "issuerId",
          "amountMinor"
        ],
        "properties": {
          "terminalId": {
            "type": "string",
            "description": "the machine, as registered on the network"
          },
          "issuerId": {
            "type": "string",
            "description": "the institution that issued the card or holds the account"
          },
          "labPan": {
            "type": "string",
            "description": "Lab PAN. Sixteen digits beginning with 9, which ISO/IEC 7812 reserves for national assignment, so it can never collide with a card-scheme BIN"
          },
          "accountNumber": {
            "type": "string",
            "description": "an account number instead of a card, for institutions that issue no card"
          },
          "amountMinor": {
            "type": "integer",
            "description": "minor units; money is never a float anywhere in this ecosystem"
          },
          "pin": {
            "type": "string"
          },
          "biometric": {
            "type": "boolean",
            "description": "verify the holder through the simulated identity entity instead of a PIN"
          },
          "ref": {
            "type": "string",
            "description": "the machine's own reference; the switch mints one when it is absent"
          }
        }
      },
      "CardlessOrderRequest": {
        "type": "object",
        "required": [
          "issuerId",
          "accountNumber",
          "amountMinor"
        ],
        "properties": {
          "issuerId": {
            "type": "string"
          },
          "accountNumber": {
            "type": "string"
          },
          "amountMinor": {
            "type": "integer"
          },
          "channel": {
            "type": "string",
            "example": "app"
          },
          "delivery": {
            "type": "string",
            "enum": [
              "code",
              "qr"
            ]
          }
        }
      },
      "AtmDepositRequest": {
        "type": "object",
        "required": [
          "terminalId",
          "issuerId"
        ],
        "properties": {
          "terminalId": {
            "type": "string"
          },
          "issuerId": {
            "type": "string"
          },
          "labPan": {
            "type": "string"
          },
          "accountNumber": {
            "type": "string"
          },
          "declaredMinor": {
            "type": "integer",
            "description": "what the depositor says they put in"
          },
          "notes": {
            "type": "array",
            "description": "the notes the machine counted; the recognition model decides what is credited",
            "items": {
              "type": "object",
              "properties": {
                "denominationMinor": {
                  "type": "integer"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "MachineTransaction": {
        "type": "object",
        "description": "What the switch recorded, including the ISO 8583 projection of the 0200 request and the 0210 response.",
        "properties": {
          "ref": {
            "type": "string"
          },
          "stan": {
            "type": "string",
            "description": "system trace audit number, DE011"
          },
          "kind": {
            "type": "string",
            "enum": [
              "withdrawal",
              "cardless-withdrawal",
              "deposit",
              "remittance-payout",
              "echo"
            ]
          },
          "terminalId": {
            "type": "string"
          },
          "issuerId": {
            "type": "string"
          },
          "operatorParticipant": {
            "type": "string"
          },
          "amountMinor": {
            "type": "integer"
          },
          "currency": {
            "type": "string",
            "enum": [
              "DOP",
              "USD",
              "EUR"
            ]
          },
          "approved": {
            "type": "boolean"
          },
          "responseCode": {
            "type": "string",
            "description": "ISO 8583 DE039. 00 approved, 51 insufficient funds, 55 incorrect PIN, 75 PIN tries exceeded, 54 expired card, 14 invalid card"
          },
          "detail": {
            "type": "string"
          },
          "iso8583": {
            "type": "object",
            "properties": {
              "request": {
                "$ref": "#/components/schemas/Iso8583Message"
              },
              "response": {
                "$ref": "#/components/schemas/Iso8583Message"
              }
            }
          }
        }
      },
      "Iso8583Message": {
        "type": "object",
        "description": "A JSON projection of an ISO 8583 message: the same data elements, by their ISO field numbers. The packed wire encoding is Phase 2; the PAN is always masked. The choice of MTIs, data elements and response codes is assumption A-07.",
        "properties": {
          "mti": {
            "type": "string",
            "enum": [
              "0100",
              "0110",
              "0200",
              "0210",
              "0420",
              "0430",
              "0800",
              "0810"
            ]
          },
          "de002_pan": {
            "type": "string"
          },
          "de003_processingCode": {
            "type": "string"
          },
          "de004_amountTransaction": {
            "type": "integer"
          },
          "de007_transmissionDateTime": {
            "type": "string"
          },
          "de011_stan": {
            "type": "string"
          },
          "de012_localTime": {
            "type": "string"
          },
          "de032_acquiringInstitutionId": {
            "type": "string"
          },
          "de037_retrievalReferenceNumber": {
            "type": "string"
          },
          "de039_responseCode": {
            "type": "string"
          },
          "de041_terminalId": {
            "type": "string"
          },
          "de049_currencyCode": {
            "type": "string"
          }
        }
      },
      "PaymentStatusReport": {
        "type": "object",
        "description": "ISO 20022 pacs.002 JSON projection, with a Lab extension carrying the findings raised.",
        "properties": {
          "MsgDefIdr": {
            "type": "string",
            "example": "pacs.002.001.14"
          },
          "TxInfAndSts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "OrgnlEndToEndId": {
                  "type": "string"
                },
                "TxSts": {
                  "type": "string",
                  "enum": [
                    "ACCP",
                    "ACSC",
                    "ACSP",
                    "RJCT",
                    "PDNG",
                    "CANC"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/v1/health": {
      "get": {
        "summary": "Liveness, the simulated clock, the reports backend and whether sign-in is required",
        "description": "Exempt from the team key and from sign-in: a probe that needs a credential is not a probe. Also answers on /health and, locally, on /healthz - Google's front end intercepts that last path before it reaches a Cloud Run container, which is why there are three.",
        "responses": {
          "200": {
            "description": "the gateway is up",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Liveness (alias of /v1/health)",
        "responses": {
          "200": {
            "description": "the gateway is up",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/healthz": {
      "get": {
        "summary": "Liveness (alias of /v1/health; intercepted by Google's front end on Cloud Run)",
        "responses": {
          "200": {
            "description": "the gateway is up",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/v1/actors": {
      "get": {
        "summary": "The simulated counterparts on the bus, with their fidelity tier and the ops each answers",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "the actor catalogue"
          }
        }
      }
    },
    "/v1/rules": {
      "get": {
        "summary": "The rule catalogue: every executable rule with its article and the resolution that fixed its value",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "the rule catalogue"
          }
        }
      }
    },
    "/v1/findings": {
      "get": {
        "summary": "Rule findings raised so far in this session",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "findings"
          }
        }
      }
    },
    "/v1/trace": {
      "get": {
        "summary": "The message trace of this session",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "trace entries"
          }
        }
      }
    },
    "/v1/clock/advance": {
      "post": {
        "summary": "Advance the simulated clock (stepped and accelerated modes)",
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "by": {
                    "type": "string",
                    "example": "8m"
                  }
                },
                "required": [
                  "by"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the new simulated instant"
          }
        }
      }
    },
    "/v1/payments/instant": {
      "post": {
        "summary": "SGPI instant payment, ISO 20022 pacs.008 projection in, pacs.002 out",
        "description": "Final credit within ten seconds (Art. 60-61), 24/7/365, alias addressing. A charge bearer of CRED is refused: the beneficiary of a transfer is never charged (Art. 81; Art. 56 numeral II).",
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreditTransferInstruction"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "pacs.002 payment status report",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentStatusReport"
                }
              }
            }
          },
          "422": {
            "description": "the instruction was refused; the body names the rule and its article"
          }
        }
      }
    },
    "/v1/payments/pai": {
      "post": {
        "summary": "Pagos al Instante BCRD transfer",
        "description": "Final credit within eight minutes, 07:00-23:00 local with a weekday pause 16:00-18:30. An order given OUTSIDE that schedule is not refused: it becomes effective at 08:00 on the NEXT BUSINESS DAY, so a Friday-night order lands on Monday morning. A dollar transfer needs no correspondent - it settles in the LBTR, which settles in Dominican pesos, US dollars and euros (Art. 56) - and where the beneficiary account is in another currency, named on CdtrAcct.Ccy, the originating institution converts and the conversion is recorded with the transaction (Arts. 41-42). The rates are Lab indicative figures, never quotations.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreditTransferInstruction"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "pacs.002 payment status report"
          },
          "422": {
            "description": "refused"
          }
        }
      }
    },
    "/v1/transfers/lbtr": {
      "post": {
        "summary": "High-value transfer through the LBTR",
        "description": "Gross settlement in DOP, USD or EUR. An order that the ordering participant cannot cover queues and is revocable while queued (Art. 66); the third-party credit follows within four minutes (Art. 57).",
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreditTransferInstruction"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the LBTR order and its status"
          }
        }
      }
    },
    "/v1/atm/terminals": {
      "get": {
        "summary": "The machines registered on the simulated ATM network",
        "description": "Each terminal names the participant that operates it and holds its notes, the currency it dispenses, and the notes left in its cassettes.",
        "tags": [
          "ATM and ITM"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "the terminals"
          }
        }
      }
    },
    "/v1/atm/withdrawals": {
      "post": {
        "summary": "Cardholder withdrawal at a machine",
        "description": "The switch routes the transaction to the issuer, which verifies the holder by PIN or by biometric through the simulated identity entity, authorizes, and lets the machine's operator pay out the notes. The position between issuer and operator settles net in the simulated LBTR at the end of the cycle (Art. 79). An issuer decline comes back as a 200 with `approved: false` and its ISO 8583 DE039 response code - a decline is a response, not an error, which is what a machine expects.",
        "tags": [
          "ATM and ITM"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AtmWithdrawalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the machine transaction, approved or declined",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineTransaction"
                }
              }
            }
          },
          "422": {
            "description": "the transaction could not be attempted; the body names the rule and its article"
          }
        }
      }
    },
    "/v1/atm/cardless/orders": {
      "post": {
        "summary": "Start a cardless (phygital) withdrawal on the phone",
        "description": "The holder's own institution checks the account and asks the ATM-network administrator to mint a one-time code and the QR that carries the data needed to initiate the order (Art. 78 numeral IV). The order is single-use and expires; both controls are the Lab's and are catalogued as such.",
        "tags": [
          "ATM and ITM"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardlessOrderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the order, its code and its QR payload"
          },
          "422": {
            "description": "refused"
          }
        }
      }
    },
    "/v1/atm/cardless/redemptions": {
      "post": {
        "summary": "Finish a cardless withdrawal at the machine",
        "description": "The machine sends the code the holder keyed in, or the QR it read. The order is spent exactly once.",
        "tags": [
          "ATM and ITM"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "terminalId": {
                    "type": "string"
                  },
                  "code": {
                    "type": "string"
                  },
                  "qr": {
                    "type": "string"
                  }
                },
                "required": [
                  "terminalId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the machine transaction"
          },
          "422": {
            "description": "the order is unknown, expired or already redeemed"
          }
        }
      }
    },
    "/v1/atm/deposits": {
      "post": {
        "summary": "Deposit at the machine, with note recognition",
        "description": "What the machine recognizes is what is credited. A difference between the declared and the recognized amount is recorded as an adjustment, which Art. 41 requires of the ten-year record.",
        "tags": [
          "ATM and ITM"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AtmDepositRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the machine transaction"
          },
          "422": {
            "description": "refused"
          }
        }
      }
    },
    "/v1/atm/remittance-payouts": {
      "post": {
        "summary": "Pay out a remittance in cash at the machine",
        "description": "Against a balance the beneficiary's institution already holds. The beneficiary is never charged for it (Art. 81).",
        "tags": [
          "ATM and ITM"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "terminalId": {
                    "type": "string"
                  },
                  "issuerId": {
                    "type": "string"
                  },
                  "accountNumber": {
                    "type": "string"
                  },
                  "amountMinor": {
                    "type": "integer"
                  },
                  "remittanceRef": {
                    "type": "string"
                  },
                  "biometric": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "terminalId",
                  "issuerId",
                  "accountNumber",
                  "amountMinor"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the machine transaction"
          },
          "422": {
            "description": "refused"
          }
        }
      }
    },
    "/v1/atm/balance-inquiries": {
      "post": {
        "summary": "Balance inquiry at a machine",
        "tags": [
          "ATM and ITM"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "terminalId": {
                    "type": "string"
                  },
                  "issuerId": {
                    "type": "string"
                  },
                  "accountNumber": {
                    "type": "string"
                  }
                },
                "required": [
                  "terminalId",
                  "issuerId",
                  "accountNumber"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the balance"
          }
        }
      }
    },
    "/v1/atm/echo": {
      "post": {
        "summary": "Network management echo (ISO 8583 0800/0810)",
        "description": "What a machine sends to prove the switch is alive.",
        "tags": [
          "ATM and ITM"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "the echo response"
          }
        }
      }
    },
    "/v1/atm/cycles": {
      "post": {
        "summary": "Settle the network cycle",
        "description": "Art. 79: the net result of the cycle settles in the simulated LBTR. Issuers pay the operators of the machines their cardholders used.",
        "tags": [
          "ATM and ITM"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cycleId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the cycle, its net positions and the LBTR legs that settled it"
          }
        }
      }
    },
    "/v1/webhooks": {
      "post": {
        "summary": "Register a webhook for bus notifications",
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "url"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "the subscription"
          }
        }
      }
    },
    "/v1/directory": {
      "get": {
        "summary": "La Poblacion del Lab: your team's world, in one call",
        "description": "The starting point. Every institution standing in your world with its Lab name and its personality, the machines on the floor, the aliases registered in the simulated SGPI directory, sample people with their synthetic documents and their accounts (in full and masked), the businesses, the population counts and how many people the Lab has flagged as adversaries. It also carries the identifier scheme, so nobody has to look up why a document begins with `LAB-` before deciding whether it is safe to put in a slide.\n\nScoped to your own team. Two teams on the same instance are handed two different populations, because their worlds are seeded from their team ids and share nothing.",
        "tags": [
          "La Poblacion del Lab"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "firebaseIdToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "the team's world: institutions, terminals, aliases, people, businesses"
          }
        }
      }
    },
    "/v1/worlds/reset": {
      "post": {
        "summary": "Throw your team's world away and stand a fresh one up",
        "description": "Everything the team did is gone: accounts, balances, aliases, the LBTR queue, the clock. What comes back is a new world with the same starter population, built from the same seed, so the people and their documents are the ones the directory listed before.\n\nThe run reports the team already produced are NOT gone. A report is the record, and a reset is not a way to unsay one.\n\nResets your own team's world. An admin principal may reset another team's by sending `x-lab-team`; nobody else can.",
        "tags": [
          "La Poblacion del Lab"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "firebaseIdToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "the fresh world: its seed, its instant, its actors and its population"
          },
          "403": {
            "description": "this principal may not reset a world on this instance"
          }
        }
      }
    },
    "/v1/worlds": {
      "get": {
        "summary": "Which worlds are standing on this instance",
        "description": "A team is told its own. An admin principal is told every world that has been stood up, and when.",
        "tags": [
          "La Poblacion del Lab"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "firebaseIdToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "the worlds this principal may see"
          }
        }
      }
    },
    "/v1/principal": {
      "get": {
        "summary": "Who this gateway thinks you are, which team you are, and what you may do",
        "description": "A team key answers as `kind: key` and carries the team the key belongs to; a console sign-in answers as `kind: user` with the verified email and the team TEAM_PRINCIPALS maps it to. `mayStartRuns` reflects this instance's ALLOWED_PRINCIPALS list for a person, and is always true for a team key, because a key can only ever write into its own world. `admin` is true for a principal on ADMIN_PRINCIPALS, who sees every team's runs and may act on any team's world with the `x-lab-team` header.",
        "tags": [
          "Runs and reports"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "firebaseIdToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "the principal"
          }
        }
      }
    },
    "/v1/scenarios": {
      "get": {
        "summary": "The scenarios in this instance, with their variants",
        "tags": [
          "Runs and reports"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "firebaseIdToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "the scenario catalogue"
          }
        }
      }
    },
    "/v1/runs": {
      "get": {
        "summary": "The run reports YOUR TEAM holds, newest first",
        "description": "Scoped to the caller: a team sees its own runs and nobody else's, and an admin principal sees every team's. A report id carries its team in front of the run id, so asking for another team's report by id answers 404 - the same answer as for a report that does not exist, which is what stops the listing being enumerable from outside.\n\nBacked by `REPORTS_BACKEND`: reports on disk, which is what makes a run reproducible by anybody holding the file, or in the project's Firestore, which is what a Cloud Run instance needs because it loses its filesystem on restart. The answer is the same either way.",
        "tags": [
          "Runs and reports"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "firebaseIdToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "one summary row per run"
          }
        }
      },
      "post": {
        "summary": "Run a scenario and keep the report",
        "description": "Requires a signed-in principal on the instance's allow-list when AUTH_REQUIRED is on.",
        "tags": [
          "Runs and reports"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "firebaseIdToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scenario": {
                    "type": "string"
                  },
                  "variant": {
                    "type": "string"
                  },
                  "seed": {
                    "type": "string"
                  }
                },
                "required": [
                  "scenario"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "the run started, finished and was kept"
          },
          "403": {
            "description": "the principal may not start runs on this instance"
          },
          "422": {
            "description": "the run could not be started"
          }
        }
      }
    },
    "/v1/runs/{id}": {
      "get": {
        "summary": "One run report in full, with its trace, ledgers and reconciliation",
        "tags": [
          "Runs and reports"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "firebaseIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "the report"
          },
          "404": {
            "description": "no report with that id"
          }
        }
      }
    },
    "/v1/runs/{id}/report.md": {
      "get": {
        "summary": "The same run report as rendered Markdown",
        "description": "The document a team attaches to an Art. 83 request as evidence, and nothing more.",
        "tags": [
          "Runs and reports"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "firebaseIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "the report",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "no report with that id"
          }
        }
      }
    },
    "/v1/actors/identity/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Registro e Identidad del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: lookup, verify",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "lookup",
                "verify"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/credit-bureau/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Buro de Credito del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: inquiry, history",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "inquiry",
                "history"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/central-bank/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Banco Central del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: registerParticipant, openCurrentAccount, creditCurrentAccount, currentAccountBalance, issueAccountNumber, validateAccountNumber, lbtr.submit, lbtr.revoke, lbtr.status, lbtr.queue, lbtr.endOfDayFlush, sgpi.registerAlias, sgpi.resolveAlias, sgpi.pay, pai.submit, pai.raiseClaim, pai.answerClaim, pai.claims, net.settle, vigilancia.report",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "registerParticipant",
                "openCurrentAccount",
                "creditCurrentAccount",
                "currentAccountBalance",
                "issueAccountNumber",
                "validateAccountNumber",
                "lbtr.submit",
                "lbtr.revoke",
                "lbtr.status",
                "lbtr.queue",
                "lbtr.endOfDayFlush",
                "sgpi.registerAlias",
                "sgpi.resolveAlias",
                "sgpi.pay",
                "pai.submit",
                "pai.raiseClaim",
                "pai.answerClaim",
                "pai.claims",
                "net.settle",
                "vigilancia.report"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/banco-norte/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Banco Norte del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: onboardCustomer, openAccount, deposit, balance, accountInfo, internalTransfer, transfer, registerAlias, postIncomingCredit, ddc.debitOriginator, ddc.reverse, lbtr.creditNotice, lbtr.revocationNotice, lbtr.revoked, sgpi.notification, cb.currentAccountCredited, atm.withdraw, records.query, records.attest, customer, issueCard, card, cards, atm.authorizeWithdrawal, atm.postDeposit, atm.terminalCashOut, atm.terminalCashIn, cardless.request, monitoring.feed, monitoring.resolveCard",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "onboardCustomer",
                "openAccount",
                "deposit",
                "balance",
                "accountInfo",
                "internalTransfer",
                "transfer",
                "registerAlias",
                "postIncomingCredit",
                "ddc.debitOriginator",
                "ddc.reverse",
                "lbtr.creditNotice",
                "lbtr.revocationNotice",
                "lbtr.revoked",
                "sgpi.notification",
                "cb.currentAccountCredited",
                "atm.withdraw",
                "records.query",
                "records.attest",
                "customer",
                "issueCard",
                "card",
                "cards",
                "atm.authorizeWithdrawal",
                "atm.postDeposit",
                "atm.terminalCashOut",
                "atm.terminalCashIn",
                "cardless.request",
                "monitoring.feed",
                "monitoring.resolveCard"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/banco-del-sur/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Banco del Sur del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: onboardCustomer, openAccount, deposit, balance, accountInfo, internalTransfer, transfer, registerAlias, postIncomingCredit, ddc.debitOriginator, ddc.reverse, lbtr.creditNotice, lbtr.revocationNotice, lbtr.revoked, sgpi.notification, cb.currentAccountCredited, atm.withdraw, records.query, records.attest, customer, issueCard, card, cards, atm.authorizeWithdrawal, atm.postDeposit, atm.terminalCashOut, atm.terminalCashIn, cardless.request, monitoring.feed, monitoring.resolveCard",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "onboardCustomer",
                "openAccount",
                "deposit",
                "balance",
                "accountInfo",
                "internalTransfer",
                "transfer",
                "registerAlias",
                "postIncomingCredit",
                "ddc.debitOriginator",
                "ddc.reverse",
                "lbtr.creditNotice",
                "lbtr.revocationNotice",
                "lbtr.revoked",
                "sgpi.notification",
                "cb.currentAccountCredited",
                "atm.withdraw",
                "records.query",
                "records.attest",
                "customer",
                "issueCard",
                "card",
                "cards",
                "atm.authorizeWithdrawal",
                "atm.postDeposit",
                "atm.terminalCashOut",
                "atm.terminalCashIn",
                "cardless.request",
                "monitoring.feed",
                "monitoring.resolveCard"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/coop-del-lab/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Cooperativa del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: onboardCustomer, openAccount, deposit, balance, accountInfo, internalTransfer, transfer, registerAlias, postIncomingCredit, ddc.debitOriginator, ddc.reverse, lbtr.creditNotice, lbtr.revocationNotice, lbtr.revoked, sgpi.notification, cb.currentAccountCredited, atm.withdraw, records.query, records.attest, customer, issueCard, card, cards, atm.authorizeWithdrawal, atm.postDeposit, atm.terminalCashOut, atm.terminalCashIn, cardless.request, monitoring.feed, monitoring.resolveCard",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "onboardCustomer",
                "openAccount",
                "deposit",
                "balance",
                "accountInfo",
                "internalTransfer",
                "transfer",
                "registerAlias",
                "postIncomingCredit",
                "ddc.debitOriginator",
                "ddc.reverse",
                "lbtr.creditNotice",
                "lbtr.revocationNotice",
                "lbtr.revoked",
                "sgpi.notification",
                "cb.currentAccountCredited",
                "atm.withdraw",
                "records.query",
                "records.attest",
                "customer",
                "issueCard",
                "card",
                "cards",
                "atm.authorizeWithdrawal",
                "atm.postDeposit",
                "atm.terminalCashOut",
                "atm.terminalCashIn",
                "cardless.request",
                "monitoring.feed",
                "monitoring.resolveCard"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/epe-lab/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on EPE del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: openEPaymentAccount, agentOperation, balance, accountInfo, addCredential, inboundRemittance, socialSubsidy, chequeFunding, registerAlias, postIncomingCredit, reconcileFloat, dailyReport, headroom, raiseClaim, answerClaim, claims, sgpi.notification, cb.currentAccountCredited, agents, atm.authorizeWithdrawal, atm.postDeposit, monitoring.feed",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "openEPaymentAccount",
                "agentOperation",
                "balance",
                "accountInfo",
                "addCredential",
                "inboundRemittance",
                "socialSubsidy",
                "chequeFunding",
                "registerAlias",
                "postIncomingCredit",
                "reconcileFloat",
                "dailyReport",
                "headroom",
                "raiseClaim",
                "answerClaim",
                "claims",
                "sgpi.notification",
                "cb.currentAccountCredited",
                "agents",
                "atm.authorizeWithdrawal",
                "atm.postDeposit",
                "monitoring.feed"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/ddc-administrator/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Administrador DD/DC del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: submitBatch, runCycle, batch, cycles, reasonCodes",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "submitBatch",
                "runCycle",
                "batch",
                "cycles",
                "reasonCodes"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/atm-network/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Red de Cajeros del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: registerTerminal, terminals, terminal, withdraw, cardless.order, cardless.redeem, cardless.status, cardless.cancel, deposit, remittancePayout, balanceInquiry, networkEcho, settleCycle, transactions, positions",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "registerTerminal",
                "terminals",
                "terminal",
                "withdraw",
                "cardless.order",
                "cardless.redeem",
                "cardless.status",
                "cardless.cancel",
                "deposit",
                "remittancePayout",
                "balanceInquiry",
                "networkEcho",
                "settleCycle",
                "transactions",
                "positions"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/monitoring/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Unidad de Monitoreo del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83.\n\nOperations: run, alerts, score, movements, thresholds",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "run",
                "alerts",
                "score",
                "movements",
                "thresholds"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/acquirer/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Adquirente del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83. Stub tier: canned responses, no state.\n\nOperations: affiliateMerchant, authorize, capture, refund, chargeback, settlementReport",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "affiliateMerchant",
                "authorize",
                "capture",
                "refund",
                "chargeback",
                "settlementReport"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/sub-acquirer/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Subadquirente del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83. Stub tier: canned responses, no state.\n\nOperations: onboardSubMerchant, authorize, payout",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "onboardSubMerchant",
                "authorize",
                "payout"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/card-processor-a/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Procesador de Tarjetas A del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83. Stub tier: canned responses, no state.\n\nOperations: authorize, clearing, settlement, tokenize, threeDSecure, iso8583",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "authorize",
                "clearing",
                "settlement",
                "tokenize",
                "threeDSecure",
                "iso8583"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/card-processor-b/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Procesador de Tarjetas B del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83. Stub tier: canned responses, no state.\n\nOperations: authorize, clearing, settlement, tokenize, threeDSecure, iso8583",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "authorize",
                "clearing",
                "settlement",
                "tokenize",
                "threeDSecure",
                "iso8583"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/wallet/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Billetera del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83. Stub tier: canned responses, no state.\n\nOperations: enrolInstrument, presentQr, readQr",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "enrolInstrument",
                "presentQr",
                "readQr"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/initiation/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Iniciador de Pagos del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83. Stub tier: canned responses, no state.\n\nOperations: requestConsent, initiate",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "requestConsent",
                "initiate"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/gateway-provider/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Pasarela del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83. Stub tier: canned responses, no state.\n\nOperations: createCheckout, webhook",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "createCheckout",
                "webhook"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/supervisor/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Superintendencia del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83. Stub tier: canned responses, no state.\n\nOperations: submitReport, requestRecords",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "submitReport",
                "requestRecords"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    },
    "/v1/actors/uaf/ops/{op}": {
      "post": {
        "summary": "Invoke an operation on Unidad de Analisis Financiero del Lab",
        "description": "Simulated counterpart operated by the CEMI Financial Innovation Lab. Not a real institution, not endorsed by the entity it is modelled after, and not an ambiente de prueba under Art. 83. Stub tier: canned responses, no state.\n\nOperations: suspiciousTransactionReport, cashTransactionReport",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "op",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "suspiciousTransactionReport",
                "cashTransactionReport"
              ]
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the operation result"
          },
          "422": {
            "description": "the operation was refused"
          }
        }
      }
    }
  }
}