CEMI

Technical manual

Virtual Financial Ecosystem Simulation - CEMI Financial Innovation Lab
English Español Français : bientôt

1What this is

A digital twin of the financial ecosystem: simulated counterparts of every institution a payment or financial application must talk to in the Dominican Republic, organized exactly as the Central Bank organizes the real thing.

Each counterpart speaks the real message format of its kind, keeps state - accounts, balances, orders, cases - obeys the rules the Reglamento sets, and can be put into failure modes. Your team plugs its application in and runs an entire process end to end, from onboarding to settlement in the simulated LBTR, without touching a real institution, a real person or real money. Every message is recorded and the run produces an instrumented report.

The value is not any single simulator. It is that all of them exist together, consistently, in one place, with one synthetic population moving through them, so a process that crosses six organizations can be exercised as one process under the rules that will apply when it is real.

Everything here is simulated. Every institution carries a Lab name, none of them is the entity it is modelled after, and none claims its endorsement. No real credentials, keys, BINs, routing identifiers, aliases or certificates exist anywhere in the ecosystem, and no real person, institution or money is involved.

This is NOT an «ambiente de prueba» under Art. 83 of the Reglamento de Sistemas de Pago. The ecosystem involves no real providers and no real external users, so it does not fall under the no-objection regime. A run is never a substitute for the Central Bank's no objection. Where your next step is an Art. 83 request, a run report is evidence for that request and nothing more.
Today this is a simulation, not a digital twin in the strict sense: there is not yet a finished system to be a twin of, since the instant-payments system is being built now. Our aim is to become the true digital twin of the Dominican financial ecosystem as it takes shape, following the work and guidelines of the Central Bank, the Superintendencia and the industry.

What is live today

This instance runs the whole of Phase 1 and the typed contracts of Phase 2. It holds 76 catalogued rules, 12 scenarios covering 32 runs with their variants, and 46 documented endpoints.

PhaseWhat it coversState
Phase 0Actor catalogue, message contracts, scenario and rule formats, synthetic population, naming and disclaimers. Three of the four BCRD instructivos read page by page and adopted into the catalogue.complete
Phase 1Central Bank with current accounts, LBTR with its queue, priority and prelation; SGPI at stateful fidelity; Pagos al Instante; three banks with three personalities; an electronic-payment entity; the DD/DC administrator; identity and a credit bureau; the ATM network and the machine lane; the behavioural tier; a scored adversarial detection; the console; per-team worlds.live
Phase 2Acquirer and sub-acquirer at stateful tier, the packed ISO 8583 wire codec, card clearing and chargebacks, wallet and initiation providers, agents at stateful tier, the simulated supervisor and UAF, chaos injectors.typed contracts only
Phase 3Cheques and the SCC, insurers and brokers, remittance and exchange agents, SIPA, telcos and the tax authority, the rest of the adversarial catalogue.not started
Phase 4Public catalogue and self-service keys, sponsored nodes, regulator and academic access.this manual is the first part of it
A stub is honest about being a stub. The Phase 2 actors answer with canned responses behind a typed contract, so an integration written against them today keeps working when they become stateful - which is the point of shipping them early. A canned response is not a test of anything, and the endpoint reference says which tier each actor is on.

2Quick start

Five minutes: get a key, ask whether the instance is up, read your world, send a payment, open the run it produced.

1. Get a team key

A key is issued to a team, not to a person. Ask for one through the key-request form, or write to partners@cemi.ai. The Lab hands you a string beginning lab-. Put it in an environment variable and keep it out of your repository, your deploy commands and your shell history.

2. Everything else

# 1. the key never appears in a command, a file or a shell history
export FINLAB_API_KEY="<the key the Lab gave your team>"
export FINLAB="https://ecosystem.financial"

# 2. is it up, and what is it running?
curl -s "$FINLAB/v1/health" | jq

# 3. what is in your world?
curl -s -H "x-lab-api-key: $FINLAB_API_KEY" "$FINLAB/v1/directory" | jq '{
  institutions: [.institutions[] | select(.role=="bank") | .id],
  aliases: [.aliases[0:3][] | .alias],
  firstPerson: .people[0]
}'

# 4. send an instant payment, addressed by alias, in ISO 20022 shape
curl -s -X POST "$FINLAB/v1/payments/instant" \
  -H "x-lab-api-key: $FINLAB_API_KEY" -H 'content-type: application/json' \
  -d '{
    "GrpHdr": { "MsgId": "MSG-0001" },
    "CdtTrfTxInf": [{
      "PmtId": { "EndToEndId": "E2E-0001" },
      "Amt": { "InstdAmt": { "Ccy": "DOP", "value": 1500.00 } },
      "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "banco-norte" } } },
      "DbtrAcct": { "Id": { "Othr": { "Id": "<an account number from the directory>" } } },
      "CdtrAlias": "<an alias from the directory>"
    }]
  }' | jq

# 5. run a scenario end to end, and open its report
curl -s -X POST "$FINLAB/v1/runs" \
  -H "x-lab-api-key: $FINLAB_API_KEY" -H 'content-type: application/json' \
  -d '{ "scenario": "sgpi-instant-alias" }' | jq
curl -s -H "x-lab-api-key: $FINLAB_API_KEY" "$FINLAB/v1/runs" | jq '.[0]'

What just happened

  • /v1/health needs no credential at all, because a probe that needs a credential is not a probe. It tells you the rule-catalogue version the instance is running, which is the version every finding you get back is judged against.
  • /v1/directory is your team's world: institutions, machines, aliases, sample people with their synthetic documents and their accounts. Another team asking the same question gets entirely different people.
  • The payment was instructed in ISO 20022 shape - a faithful JSON projection of pain.001 - and came back with its findings: every rule it touched, each one carrying the article behind it.
  • The run report is the record. It carries the seed, so anybody holding it can reproduce the run exactly.

3Authentication

Two credentials, and they identify two different kinds of thing. A team key identifies a team. A signed-in principal identifies a person.

The team key

Sent in the x-lab-api-key header on every call. It carries the team it belongs to, and the team decides which world the request reaches - so a key opens exactly one ecosystem and can never observe, move or reach anything belonging to another team.

A key opens the whole of /v1, including the machine lane at /v1/atm/**, where it is the only credential that can possibly work: an ATM cannot hold a session. It may also start runs, because a run happens in the team's own world and its report is written under the team and visible to nobody else.

x-lab-api-key: lab-3f9a...

Signing in to the console

The console at ecosystem.financial signs in with Firebase Auth - Google, or an email and a password - and sends the ID token it is given in an Authorization: Bearer header. The gateway verifies it on every call. Which team a person belongs to is configured on the instance; a person the instance does not map falls into the default team.

What each one may do

Team keySigned-in personAdmin principal
Read the directory, the actors, the rulesits own worldits own worldany team's, with x-lab-team
Drive payments and the machine laneyesyesyes
Advance the clockits own world onlyits own world onlyany team's
Start a runyesif on the allow-listyes
List and open run reportsits own team'sits own team'severy team's
Reset a worldits ownits own, if on the allow-listany team's
Two lists, and they do different jobs. ALLOWED_PRINCIPALS decides which signed-in people may spend the Lab's compute by starting a run. ADMIN_PRINCIPALS decides who sees every team. Neither of them governs keys, because a key is already confined to one world.

Rotation and revocation

Keys live in Secret Manager and never in this repository, a deploy command or a shell history. Rotating your team's key means the Lab writes a new secret version with your old key replaced; the new key works on the next revision and the old one stops. Revoking means a version without your pair. Neither touches your run reports, which are the record.

Ask for a rotation through the feedback form or at security@cemi.ai. If you believe a key has leaked, say so immediately and do not wait to be sure - a rotation costs the Lab a minute.

4Endpoint reference

Generated from the instance's own OpenAPI document, so it cannot drift from what the gateway actually answers. The live contract is at /openapi.json and is the same document.

Error shapes

Three things can go wrong, and they are deliberately different answers.

StatusShapeWhat it means
401{ error, message }No credential, or one that did not verify. The message says which credential the lane expects.
403{ error, message }A valid credential that may not do this: a person not on the allow-list starting a run, or a team asking to act as another team.
404{ error, message }No such endpoint, or no such run that you may see. Another team's report answers 404, the same as one that does not exist, so a listing is not enumerable from outside.
422{ error, message, findings[] }A refusal. The ecosystem understood you and said no - a cap breached, a beneficiary charged, an order past its window. error is the actor's own code and findings carries every rule the attempt touched, with its article.
A refusal is the interesting answer, not the failure case. A 422 with CHARGE_TO_BENEFICIARY_REFUSED and a failing TRANSFER.NO_CHARGE_TO_BENEFICIARY finding citing Art. 81 is the ecosystem doing its job. On the machine lane the rule is different again: an issuer decline comes back 200 with approved: false and its ISO 8583 DE039 code, because that is what a machine expects - and because the declines are what makes a card-testing pattern detectable at all.

Findings: what comes back with every call

Every operation returns the rules it touched alongside its result. A finding names the rule, the article, the instrument and the resolution date, what was observed and what was expected, and when. Findings with needsRecheck come from an instructivo that cites a superseded Reglamento - the rule is live, it is just not presented as settled.

{
  "result": { "...": "the operation's own answer" },
  "findings": [
    {
      "ruleId": "SGPI.FINAL_CREDIT",
      "article": "Art. 62",
      "instrument": "Reglamento de Sistemas de Pago",
      "resolution": "Segunda Resolucion de la Junta Monetaria",
      "resolutionDate": "2025-08-28",
      "status": "pass",
      "severity": "critical",
      "actor": "central-bank",
      "observed": 1700,
      "expected": "<= 10s",
      "detail": "elapsed 1.7s against a limit of 10s (Art. 62)",
      "at": "2026-09-08T13:00:01.700Z",
      "local": "2026-09-08 09:00"
    }
  ]
}

ATM and ITM

GET /v1/atm/terminals The machines registered on the simulated ATM network

Each terminal names the participant that operates it and holds its notes, the currency it dispenses, and the notes left in its cassettes.

Credential: x-lab-api-key (team key)

Request body

No request body.

Responses

200the terminals
POST /v1/atm/withdrawals Cardholder withdrawal at a machine

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.

Credential: x-lab-api-key (team key)

Request body

{
  "$ref": "#/components/schemas/AtmWithdrawalRequest"
}

Responses

200the machine transaction, approved or declined
422the transaction could not be attempted; the body names the rule and its article
POST /v1/atm/cardless/orders Start a cardless (phygital) withdrawal on the phone

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.

Credential: x-lab-api-key (team key)

Request body

{
  "$ref": "#/components/schemas/CardlessOrderRequest"
}

Responses

200the order, its code and its QR payload
422refused
POST /v1/atm/cardless/redemptions Finish a cardless withdrawal at the machine

The machine sends the code the holder keyed in, or the QR it read. The order is spent exactly once.

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "properties": {
    "terminalId": {
      "type": "string"
    },
    "code": {
      "type": "string"
    },
    "qr": {
      "type": "string"
    }
  },
  "required": [
    "terminalId"
  ]
}

Responses

200the machine transaction
422the order is unknown, expired or already redeemed
POST /v1/atm/deposits Deposit at the machine, with note recognition

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.

Credential: x-lab-api-key (team key)

Request body

{
  "$ref": "#/components/schemas/AtmDepositRequest"
}

Responses

200the machine transaction
422refused
POST /v1/atm/remittance-payouts Pay out a remittance in cash at the machine

Against a balance the beneficiary's institution already holds. The beneficiary is never charged for it (Art. 81).

Credential: x-lab-api-key (team key)

Request body

{
  "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

200the machine transaction
422refused
POST /v1/atm/balance-inquiries Balance inquiry at a machine

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "properties": {
    "terminalId": {
      "type": "string"
    },
    "issuerId": {
      "type": "string"
    },
    "accountNumber": {
      "type": "string"
    }
  },
  "required": [
    "terminalId",
    "issuerId",
    "accountNumber"
  ]
}

Responses

200the balance
POST /v1/atm/echo Network management echo (ISO 8583 0800/0810)

What a machine sends to prove the switch is alive.

Credential: x-lab-api-key (team key)

Request body

No request body.

Responses

200the echo response
POST /v1/atm/cycles Settle the network cycle

Art. 79: the net result of the cycle settles in the simulated LBTR. Issuers pay the operators of the machines their cardholders used.

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "properties": {
    "cycleId": {
      "type": "string"
    }
  }
}

Responses

200the cycle, its net positions and the LBTR legs that settled it

La Poblacion del Lab

GET /v1/directory La Poblacion del Lab: your team's world, in one call

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.

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

Credential: x-lab-api-key (team key) or Authorization: Bearer (signed-in principal)

Request body

No request body.

Responses

200the team's world: institutions, terminals, aliases, people, businesses
POST /v1/worlds/reset Throw your team's world away and stand a fresh one up

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.

The run reports the team already produced are NOT gone. A report is the record, and a reset is not a way to unsay one.

Resets your own team's world. An admin principal may reset another team's by sending x-lab-team; nobody else can.

Credential: x-lab-api-key (team key) or Authorization: Bearer (signed-in principal)

Request body

No request body.

Responses

200the fresh world: its seed, its instant, its actors and its population
403this principal may not reset a world on this instance
GET /v1/worlds Which worlds are standing on this instance

A team is told its own. An admin principal is told every world that has been stood up, and when.

Credential: x-lab-api-key (team key) or Authorization: Bearer (signed-in principal)

Request body

No request body.

Responses

200the worlds this principal may see

Other

GET /v1/health Liveness, the simulated clock, the reports backend and whether sign-in is required

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.

Credential: none - open, so a probe never needs a credential

Request body

No request body.

Responses

200the gateway is up
GET /health Liveness (alias of /v1/health)

Credential: none - open, so a probe never needs a credential

Request body

No request body.

Responses

200the gateway is up
GET /healthz Liveness (alias of /v1/health; intercepted by Google's front end on Cloud Run)

Credential: none - open, so a probe never needs a credential

Request body

No request body.

Responses

200the gateway is up
GET /v1/actors The simulated counterparts on the bus, with their fidelity tier and the ops each answers

Credential: x-lab-api-key (team key)

Request body

No request body.

Responses

200the actor catalogue
GET /v1/rules The rule catalogue: every executable rule with its article and the resolution that fixed its value

Credential: x-lab-api-key (team key)

Request body

No request body.

Responses

200the rule catalogue
GET /v1/findings Rule findings raised so far in this session

Credential: x-lab-api-key (team key)

Request body

No request body.

Responses

200findings
GET /v1/trace The message trace of this session

Credential: x-lab-api-key (team key)

Request body

No request body.

Responses

200trace entries
POST /v1/clock/advance Advance the simulated clock (stepped and accelerated modes)

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "properties": {
    "by": {
      "type": "string",
      "example": "8m"
    }
  },
  "required": [
    "by"
  ]
}

Responses

200the new simulated instant
POST /v1/payments/instant SGPI instant payment, ISO 20022 pacs.008 projection in, pacs.002 out

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

Credential: x-lab-api-key (team key)

Request body

{
  "$ref": "#/components/schemas/CreditTransferInstruction"
}

Responses

200pacs.002 payment status report
422the instruction was refused; the body names the rule and its article
POST /v1/payments/pai Pagos al Instante BCRD transfer

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.

Credential: x-lab-api-key (team key)

Request body

{
  "$ref": "#/components/schemas/CreditTransferInstruction"
}

Responses

200pacs.002 payment status report
422refused
POST /v1/transfers/lbtr High-value transfer through the LBTR

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

Credential: x-lab-api-key (team key)

Request body

{
  "$ref": "#/components/schemas/CreditTransferInstruction"
}

Responses

200the LBTR order and its status
POST /v1/webhooks Register a webhook for bus notifications

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string"
    },
    "events": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": [
    "url"
  ]
}

Responses

201the subscription
POST /v1/actors/central-bank/ops/{op} Invoke an operation on Banco Central del Lab

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.

Operations: 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

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/bank/ops/{op} Invoke an operation on Banco del Lab

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.

Operations: 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

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/epe/ops/{op} Invoke an operation on EPE del Lab

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.

Operations: 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

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/ddc-administrator/ops/{op} Invoke an operation on Administrador de Debito y Credito Directo del Lab

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.

Operations: submitBatch, runCycle, batch, cycles, reasonCodes

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/identity/ops/{op} Invoke an operation on Registro e Identidad del Lab

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.

Operations: lookup, verify

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/credit-bureau/ops/{op} Invoke an operation on Buro de Credito del Lab

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.

Operations: inquiry, history

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/monitoring/ops/{op} Invoke an operation on Unidad de Monitoreo del Lab

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.

Operations: run, alerts, score, movements, thresholds

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/acquirer/ops/{op} Invoke an operation on Adquirente del Lab

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.

Operations: affiliateMerchant, authorize, capture, refund, chargeback, settlementReport

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/sub-acquirer/ops/{op} Invoke an operation on Subadquirente del Lab

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.

Operations: onboardSubMerchant, authorize, payout

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/card-processor/ops/{op} Invoke an operation on Procesador card-processor del Lab

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.

Operations: authorize, clearing, settlement, tokenize, threeDSecure, iso8583

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/atm-network-administrator/ops/{op} Invoke an operation on Administrador de Red de Cajeros del Lab

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.

Operations: registerTerminal, terminals, terminal, withdraw, cardless.order, cardless.redeem, cardless.status, cardless.cancel, deposit, remittancePayout, balanceInquiry, networkEcho, settleCycle, transactions, positions

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/wallet-provider/ops/{op} Invoke an operation on Billetera del Lab

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.

Operations: enrolInstrument, presentQr, readQr

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/initiation-provider/ops/{op} Invoke an operation on Iniciador de Pagos del Lab

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.

Operations: requestConsent, initiate

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/gateway-provider/ops/{op} Invoke an operation on Pasarela del Lab

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.

Operations: createCheckout, webhook

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/supervisor/ops/{op} Invoke an operation on Superintendencia del Lab

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.

Operations: submitReport, requestRecords

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused
POST /v1/actors/uaf/ops/{op} Invoke an operation on Unidad de Analisis Financiero del Lab

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.

Operations: suspiciousTransactionReport, cashTransactionReport

Credential: x-lab-api-key (team key)

Request body

{
  "type": "object",
  "additionalProperties": true
}

Responses

200the operation result
422the operation was refused

Runs and reports

GET /v1/principal Who this gateway thinks you are, which team you are, and what you may do

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.

Credential: x-lab-api-key (team key) or Authorization: Bearer (signed-in principal)

Request body

No request body.

Responses

200the principal
GET /v1/scenarios The scenarios in this instance, with their variants

Credential: x-lab-api-key (team key) or Authorization: Bearer (signed-in principal)

Request body

No request body.

Responses

200the scenario catalogue
GET /v1/runs The run reports YOUR TEAM holds, newest first

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.

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

Credential: x-lab-api-key (team key) or Authorization: Bearer (signed-in principal)

Request body

No request body.

Responses

200one summary row per run
POST /v1/runs Run a scenario and keep the report

Requires a signed-in principal on the instance's allow-list when AUTH_REQUIRED is on.

Credential: x-lab-api-key (team key) or Authorization: Bearer (signed-in principal)

Request body

{
  "type": "object",
  "properties": {
    "scenario": {
      "type": "string"
    },
    "variant": {
      "type": "string"
    },
    "seed": {
      "type": "string"
    }
  },
  "required": [
    "scenario"
  ]
}

Responses

201the run started, finished and was kept
403the principal may not start runs on this instance
422the run could not be started
GET /v1/runs/{id} One run report in full, with its trace, ledgers and reconciliation

Credential: x-lab-api-key (team key) or Authorization: Bearer (signed-in principal)

Request body

No request body.

Responses

200the report
404no report with that id
GET /v1/runs/{id}/report.md The same run report as rendered Markdown

The document a team attaches to an Art. 83 request as evidence, and nothing more.

Credential: x-lab-api-key (team key) or Authorization: Bearer (signed-in principal)

Request body

No request body.

Responses

200the report
404no report with that id

5Web services and the machine lane

Four interfaces, chosen so that a team integrates the way it would integrate for real.

InterfaceWhereWhat speaks it
REST + OpenAPIeverything under /v1an application, a test suite, a CI job
ISO 20022, JSON projection/v1/payments/*, /v1/transfers/lbtra payments application instructing pain.001 and reading pacs.002
ISO 8583, JSON projection/v1/atm/**an ATM or ITM integration; every response carries the 0200/0210 pair the switch built
WebhooksPOST /v1/webhooksanything that would rather be told than poll
The projection, precisely. What the machine lane carries is the same data elements by their ISO 8583 field numbers, in JSON, recorded next to every transaction. The packed encoding - the bitmaps, the network headers - is Phase 2 and does not exist yet. If your integration needs the wire format rather than the field semantics, say so on the feedback form: it is the single most useful thing a card processor could ask us to prioritise.

Integrating a machine, step by step

This is the walkthrough for putting a real ATM or ITM - or a simulator of one - on the lane.

  1. Hold a team key on the device. The machine lane is the one lane where a key is not a convenience: hardware cannot hold a session, so the key is the credential. Provision it the way you would provision any device secret.
  2. Echo first. POST /v1/atm/echo is what a switch sends before it trusts a link. It costs nothing and it tells you the network is reachable and the key is good.
  3. Read the terminals. GET /v1/atm/terminals lists the machines standing in your world, their cassettes, their operator institution and whether they accept deposits. One of the four is deliberately out of cash, so your out-of-service path has something to exercise against.
  4. Register your own terminal if you are driving real hardware: POST /v1/actors/atm-network/ops/registerTerminal with your terminal id, its operator, its cassette and whether it accepts deposits.
  5. Drive a cardholder withdrawal. The PAN and the PIN are returned once at issuance and never leave the issuer: the switch sees a masked PAN and the issuer's verdict. Read approved, and on a refusal read the DE039 response code rather than treating it as an error.
  6. Drive the cardless flow if you support it. The order is raised on the phone at the holder's own institution and finished at the machine, exactly once and inside its validity. The QR payload is the Lab string LAB-QR:v1:<network>:<orderId>:<code> - the Central Bank's QR instructivo is not published, and the Lab does not invent one.
  7. Close the cycle. The network holds no money and keeps no book: it is an indirect participant. POST /v1/atm/cycles settles the day's net position in the simulated LBTR under Art. 79, and the report shows the gross legs it took to get there.
# The machine lane is what an ATM or ITM integration drives. It is the one lane where a
# team key is not a convenience but the only possible credential: hardware cannot hold a
# session, so it presents a key and nothing else.
export FINLAB="https://ecosystem.financial"
K="x-lab-api-key: $FINLAB_API_KEY"

# 0. the machines standing in your world, with their cassettes and their operator
curl -s -H "$K" "$FINLAB/v1/atm/terminals" | jq

# 1. a network echo, which is what a switch sends before it trusts a link
curl -s -X POST -H "$K" -H 'content-type: application/json' "$FINLAB/v1/atm/echo" -d '{}' | jq

# 2. a cardholder withdrawal. The PAN and the PIN come from the issuer at issuance and
#    never leave it: the switch sees a masked PAN and the issuer's verdict, nothing more.
curl -s -X POST -H "$K" -H 'content-type: application/json' "$FINLAB/v1/atm/withdrawals" -d '{
  "terminalId": "TERM-LAB-0001",
  "labPan": "<the PAN issued to the card>",
  "pin": "<the PIN returned once at issuance>",
  "amountMinor": 200000,
  "currency": "DOP"
}' | jq '{approved, responseCode, iso8583: .result.iso8583.DE039}'

# A DECLINE IS A RESPONSE, NOT AN ERROR. An issuer refusal comes back 200 with
# approved:false and its ISO 8583 DE039 code, because that is what a machine expects -
# and because the declines are what makes a card-testing pattern detectable at all.

# 3. the cardless flow: the order is raised on the phone, at the holder's own institution
ORDER=$(curl -s -X POST -H "$K" -H 'content-type: application/json' "$FINLAB/v1/atm/cardless/orders" -d '{
  "issuerId": "banco-norte",
  "accountNumber": "<an account number from the directory>",
  "amountMinor": 300000
}')
echo "$ORDER" | jq '{orderId: .result.orderId, code: .result.code, qr: .result.qr}'

# 4. and finished at the machine, exactly once and inside its validity
curl -s -X POST -H "$K" -H 'content-type: application/json' "$FINLAB/v1/atm/cardless/redemptions" -d '{
  "terminalId": "TERM-LAB-0002",
  "code": "<the one-time code from step 3>"
}' | jq

# 5. a deposit the machine counted and recognized
curl -s -X POST -H "$K" -H 'content-type: application/json' "$FINLAB/v1/atm/deposits" -d '{
  "terminalId": "TERM-LAB-0002",
  "labPan": "<the PAN>",
  "pin": "<the PIN>",
  "amountMinor": 500000
}' | jq

# 6. close the cycle: the network holds no money and keeps no book, so the day's net
#    position settles in the simulated LBTR (Art. 79)
curl -s -X POST -H "$K" -H 'content-type: application/json' "$FINLAB/v1/atm/cycles" -d '{}' | jq

6La Población del Lab

Every team world is born holding the same documented starter dataset, so a developer with a fresh key does not have to invent an ecosystem before making a real call.

The institutions

ActorLab nameWhat it is
banco-norteBanco Norte del Labstrict-legacy - branch-first, conservative at the door, batch-shaped posting habits
banco-del-surBanco del Sur del Labpermissive-digital - app-first, onboards remotely in seconds, leans on monitoring rather than on the door
coop-del-labCooperativa del Labcooperative - member-owned, accepts a thin file because membership is the relationship
epe-labEPE del LabElectronic-payment entity: electronic payment accounts, three agents, the Art. 78 numeral II caps
ddc-administratorAdministrador DD/DC del LabDirect-debit and direct-credit administrator: batches, cycles on a business calendar, returns, net settlement
atm-networkRed de Cajeros del LabATM-network administrator: four machines, one of them deliberately out of cash
central-bankBanco Central del LabLBTR, SGPI, Pagos al Instante, the participants' current accounts, the account standard
The cooperative is not decoration. The plan claims that a bank personality is data, and that a cooperative, a savings-and-loan or a sponsored bank drops in without touching the bank class. The third personality is that claim, exercised.

The people, and what they hold

WhatHow many
synthetic people200
businesses40
people onboarded at a bank, round-robin across the three90
of those, holding a debit card30
electronic payment accounts at the EPE30
aliases registered in the simulated SGPI directory45
businesses with an account20
people the Lab has flagged as adversaries12

The counts are ceilings, not guarantees, and deliberately so: the seeder goes through each institution's own front door, calling the same onboarding a team calls. Banco Norte is a strict institution and it is supposed to refuse people. A starter dataset that quietly bypassed its own door would be teaching the wrong thing in the first minute of the first day.

Opening balances

AccountOpening balance
each bank's own current account at the simulated Central BankRD$50,000,000.00
the EPE's float, which must cover every managed balanceRD$5,000,000.00
a personal sight accountRD$25,000.00
a business accountRD$400,000.00
an electronic payment accountRD$8,000.00

Why no identifier here can be mistaken for a real one

IdentifierScheme, and why it cannot be real
personLAB-###-#######-# - the 3-7-1 shape of a cedula de identidad y electoral, so field widths, input masks and validators exercise correctly, behind a LAB- prefix a real cedula can never carry, because a real cedula is eleven digits and separators and never a letter. The prefix is what makes it unmistakably synthetic; the Lab makes no claim about which digit blocks have or have not been issued.
businessLAB-RNC-######### - the nine digits of a Registro Nacional de Contribuyente behind the same LAB- prefix.
accountLB + two check digits + a four-character institution code + sixteen digits, the shape of the regional standardized account number with the country prefix deliberately LB and never DO (assumption A-02).
cardA PAN whose issuer identification number begins with 9 - the range ISO/IEC 7812 reserves for national assignment - so it can never collide with a card-scheme BIN. The check digit is a real Luhn digit, so a validator behaves correctly.
phone+1-809-555-#### - the 555 exchange, which is not routed to subscribers. NANP formally reserves only 555-0100 to 555-0199 for fictional use; the Lab uses the whole exchange because two hundred people do not fit in a hundred numbers, and that widening is a Lab decision (assumption A-24).
emailname@lab.invalid - .invalid is reserved by RFC 2606 and can never be delegated.
alias@name#### - the SGPI alias, unique inside one world and meaningless outside it.

The same block travels with every GET /v1/directory response, so nobody has to come back here before deciding whether a number is safe to put in a slide.

The adversaries

Twelve of the two hundred are flagged: two mule rings of a controller and three mules each, and four card testers. They are drawn from the end of the population so nobody a scenario needed is quietly turned into a mule, and their onboarding-facing traits are forced clean - because a recruited mule is recruited for exactly that: papers that pass. The pattern has to be found in the movements, never at the door.

The Lab's knowledge of who they are is the oracle a run scores a detection against. Nothing that performs detection may read it, and the monitoring unit reads it only after its alerts already exist.

Resetting your world

POST /v1/worlds/reset throws your team's world away and stands a fresh one up from the same seed. The people come back with the same documents and the same accounts; everything they did does not. Your run reports survive a reset, because a report is the record and a reset is not a way to unsay one.

7Scenarios

A scenario is a whole process, written down: a cast, a clock, a population, a sequence of steps with their expectations, and a declaration of the rules it claims to exercise.

Every scenario declares what it cites, and the report lists anything cited but not reached. A scenario that claims a rule and never touches it is a failing scenario. That is not a nicety - it is what stops a catalogue of rules from becoming a catalogue of intentions.

A variant runs the same scenario down a different course: the applicant who is a minor, the machine that runs out of notes, the order that arrives after the window closed, the institution misconfigured to charge the beneficiary. Start one with { "scenario": "...", "variant": "..." }, and pass your own seed to make the run reproducible by anybody you hand the seed to.

adversarial-detectionA mule ring, a card-testing run, and a monitoring unit that is scored on both

The first adversarial run. The synthetic population is asked for a mule ring - three accounts that collect from elsewhere and pass almost everything straight on to a controller - and for a card tester, who tries a card at a machine again and again with a PIN they do not have. The institutions behave normally throughout: nobody is refused for being an adversary, because nothing in the ecosystem knows who is one. Then the simulated monitoring unit consumes what Arts. 43-44 make available - the institutions' own movement records and the network's machine transactions, refusals included - looks for two patterns, and raises alerts. Only afterwards does it read the Lab's own ground truth, which is the one place that knows who was made an adversary, and score itself against it. Neither pattern nor any threshold in it comes from the Reglamento. Art. 43 makes the Ley 155-17 obligation apply and Art. 44 puts the records at the supervisors' disposal; what to look for in them is the Lab's decision, recorded as assumption A-23. A score is a score on this run, this seed and these thresholds. The banks run at the BEHAVIOURAL fidelity tier: the legacy core under a busy-branch-day profile, with jitter, a queue and a long tail; the digital bank on a cautious fraud desk that refuses one machine withdrawal in twenty on its own suspicion, whatever the balance says. The patterns have to be found through that, not in spite of it.

Process: 6.14 Fraud and adversarial - mule networks and card testing in the synthetic population, with a run that scores the detection · Seed: finlab-adversarial-2026

Variants

  • no-pattern-nothing-to-find - The same institutions, the same monitoring, and nobody doing anything. The other half of a detection claim, and the half that is usually missing: a run with no pattern in it must raise no alert. A monitoring unit that finds a mule ring in an ordinary day is not a detection, it is a noise generator.

Rules it claims to exercise

AML.TRANSACTION_MONITORING ATM.CARDHOLDER_VERIFICATION RECORDS.INCLUDES_REJECTED RECORDS.RETENTION_YEARS TRANSFER.NO_CHARGE_TO_BENEFICIARY ACCOUNT.STANDARD_NUMBER SIPARD.INTEROPERABILITY

atm-cardholder-withdrawalCardholder withdrawal and deposit at a machine of another institution

A customer of the permissive digital bank takes cash out of a machine that the strict legacy bank operates, and then puts notes back into it. The card is one the issuer issued, the PIN is verified at the issuer, and the switch between the machine and the host is the simulated ATM-network administrator at stateful fidelity. Neither institution moves money to the other at the moment of the withdrawal: the position between them joins the network's cycle, and the cycle's net result settles in the simulated LBTR, which is what Art. 79 requires of every clearing cycle of the electronic-instrument systems. The variants are the two things a machine on the Lab floor will do most often by accident: a wrong PIN until the card blocks, and a machine that has run out of notes.

Process: 6.3 Cards / 6.4 ATM-ITM - withdrawal at a machine through the simulated network administrator, deposit with recognition, and settlement of the network's net result in the LBTR (Art. 79) · Seed: finlab-atm-2026

Variants

  • wrong-pin-blocks-the-card - Three wrong PINs and the card is blocked. A machine on a Lab floor sees a wrong PIN more often than anything else. The issuer counts the attempts, blocks the card on the third, and every refusal is retained in the ten-year record with its response code (Art. 41).
  • machine-out-of-notes - The machine has no notes left. The switch refuses before it ever troubles the issuer, and says so with DE039 51.

Rules it claims to exercise

ATM.CARDHOLDER_VERIFICATION ATM.DEPOSIT_DISCREPANCY_RECORDED NET.SETTLES_IN_LBTR NET.DEFERRED_FINALITY LBTR.SETTLEMENT_CURRENCY SIPARD.INTEROPERABILITY SIPARD.DIRECT_PARTICIPANT_HAS_CB_ACCOUNT CAPITAL.EPE_SUBACQUIRER_ATM_WALLET ACCOUNT.STANDARD_NUMBER RECORDS.RETENTION_YEARS RECORDS.INCLUDES_REJECTED

atm-cardless-withdrawalCardless withdrawal started on the phone and finished at the machine

The phygital flow the Lab floor is built for. A customer opens the bank's app, asks for cash without a card, and the simulated ATM-network administrator mints a one-time code and the QR that carries the data needed to initiate the order - which is what Art. 78 numeral IV requires every provider to be able to present and read. Minutes later the customer walks up to a machine of another institution, keys the code, and takes the notes. Nothing authenticates at the machine: the order was authenticated on the phone, and the order is spent exactly once. The second half is the other thing these machines are for in this country: a remittance that arrived at an electronic-payment entity is paid out in cash at the machine, in full, because the beneficiary of a payment is never charged for receiving it (Art. 81).

Process: 6.4 ATM-ITM phygital - cardless withdrawal started on the phone and finished on the machine, and a remittance paid out in cash at the machine · Seed: finlab-atm-cardless-2026

Variants

  • order-redeemed-twice - The same code presented at the machine a second time. An order is spent once. A replay is refused, and the rule that refuses it says so by name.
  • order-expired-before-the-machine - The holder took too long to reach the machine. The order is minted with a five-minute validity and the holder arrives after six. The machine refuses, and the account is never touched.

Rules it claims to exercise

ATM.CARDLESS_ORDER_SINGLE_USE ATM.CARDHOLDER_VERIFICATION QR.PRESENT_AND_READ TRANSFER.NO_CHARGE_TO_BENEFICIARY EPA.PERMITTED_OPERATION EPA.BALANCE_CAP NET.SETTLES_IN_LBTR SIPARD.INTEROPERABILITY ACCOUNT.STANDARD_NUMBER

charge-to-beneficiary-must-failA bank that charges the beneficiary must fail

A misconfigured institution is put on the bus on purpose. Its personality carries chargesBeneficiary, so it builds its instructions with an ISO 20022 charge bearer of CRED - the charge borne by the creditor. The Reglamento does not allow it: Art. 81 and Art. 56 numeral II say the beneficiary of a transfer or payment is never charged. The run proves that the rule bites on the institution's own internal transfer, and again at the simulated Central Bank when the instruction reaches the SGPI. This scenario is expected to raise failed findings: that is the point of it.

Process: 6.2 Electronic funds transfers - variant: beneficiary charged (must fail, Art. 81) · Seed: finlab-art81-2026

Variants

No variants.

Rules it claims to exercise

TRANSFER.NO_CHARGE_TO_BENEFICIARY SGPI.MANDATORY_PARTICIPATION RECORDS.INCLUDES_REJECTED

direct-credit-with-returnPayroll by direct credit, with one item returned

An employer hands a payroll file to the simulated direct-debit and direct-credit administrator. The originator's account is debited when the file is accepted. At the clearing cycle each item is applied at the receiving institution; one of them names an account that does not exist, so it comes back with a reason code and the originator is made whole. The net position of the cycle then settles in the simulated LBTR, which is what Art. 79 requires of the results of a clearing cycle.

Process: 6.2 Electronic funds transfers - direct credit through the simulated administrator with returns; 6.12 Business - payroll · Seed: finlab-ddc-2026

Variants

  • weekend-cycle - A clearing cycle attempted on a Sunday

Rules it claims to exercise

DDC.CYCLE_ON_BUSINESS_DAY DDC.RETURN_CARRIES_REASON_CODE NET.SETTLES_IN_LBTR NET.DEFERRED_FINALITY SIPARD.INTEROPERABILITY RECORDS.INCLUDES_REJECTED

internal-transferInternal transfer between two accounts at one bank

The simplest movement in the ecosystem, and the one every integration starts with: two customers of the same institution, one transfer, no system in between. The run checks that the beneficiary is not charged (Art. 81), that the ordering party bears the fixed fee, that the bank's book balances, and that the movement is in the ten-year record. The variant asks for more than the account holds.

Process: 6.2 Electronic funds transfers - internal · Seed: finlab-internal-2026

Variants

  • insufficient-funds - The ordering account does not hold the amount

Rules it claims to exercise

TRANSFER.NO_CHARGE_TO_BENEFICIARY ACCOUNT.STANDARD_NUMBER RECORDS.RETENTION_YEARS RECORDS.INCLUDES_REJECTED

lbtr-foreign-currencyHigh-value settlement in dollars and in euros

The LBTR settles continuously in Dominican pesos, US dollars and euros, and Art. 56 puts national and foreign currency on the same footing. Until now every scenario moved pesos, and the currency rule was checked against a single member of its own list. This one moves a hundred thousand dollars between two participants that hold dollar current accounts at the simulated Central Bank, credits the beneficiary within the four minutes Art. 57 allows, and does the same in euros in its variant. Each currency has its own current account and its own queue: a participant with pesos to spare and no dollars cannot settle a dollar order, which is the point of the third variant.

Process: 6.2 Electronic funds transfers - high-value through the LBTR in foreign currency (Art. 56: national and foreign currency) · Seed: finlab-fx-lbtr-2026

Variants

  • euros - The same settlement in euros. The third of the LBTR's currencies, exercised the same way. Nothing in the flow changes but the current account the order is drawn on, which is the property worth proving.
  • no-liquidity-in-that-currency - Pesos in the vault, no dollars in the account. Each currency has its own current account at the simulated Central Bank and its own queue. A participant seeded only in pesos cannot settle a dollar order: the order queues, and it queues in dollars.

Rules it claims to exercise

LBTR.SETTLEMENT_CURRENCY LBTR.THIRD_PARTY_CREDIT LBTR.IRREVOCABLE_ONCE_SETTLED SIPARD.DIRECT_PARTICIPANT_HAS_CB_ACCOUNT ACCOUNT.STANDARD_NUMBER RECORDS.RETENTION_YEARS

lbtr-high-valueHigh-value transfer through the LBTR, with a queue and a revocation

A high-value order arrives at the simulated LBTR while the ordering bank's current account at the Central Bank does not cover it, so the order queues. Queued, it is revocable, and the run revokes it and watches the debit come back. The Central Bank then credits the bank's current account, a second order settles gross, the receiving bank posts the third-party credit inside the four minutes of Art. 57, and a revocation of the settled order is refused: once settled, an order is irrevocable (Art. 66).

Process: 6.2 Electronic funds transfers - high value through the LBTR with the four-minute third-party credit and irrevocability once settled · Seed: finlab-lbtr-2026

Variants

No variants.

Rules it claims to exercise

LBTR.SETTLEMENT_CURRENCY LBTR.REVOCABLE_WHILE_QUEUED LBTR.IRREVOCABLE_ONCE_SETTLED LBTR.THIRD_PARTY_CREDIT SIPARD.DIRECT_PARTICIPANT_HAS_CB_ACCOUNT

onboarding-account-openingOnboarding and account opening at two banks with different appetites

The same applicant walks into the strict legacy bank and the permissive digital bank. Identity is verified against the simulated civil registry with document and, where the institution requires it, liveness; the bureau is queried; the institution's own policy decides. The run then opens an electronic payment account and funds it, and the RD$79,000 cap of Art. 78 numeral II is enforced on the way in. The variants are the cases a real onboarding desk actually meets: a politically exposed person, a minor, a thin file, a poor document capture, and a funding that would breach the cap.

Process: 6.1 Onboarding and account opening - identity, bureau, risk scoring, account or e-payment account creation (Art. 19), first funding · Seed: finlab-onboarding-2026

Variants

  • pep-hit - The applicant is a politically exposed person
  • minor-applicant - The applicant is a minor
  • thin-file - A thin credit file, refused by one bank and accepted by the other
  • document-mismatch - The document capture is too poor to verify
  • cap-reached - Funding that would breach the RD$79,000 cap

Rules it claims to exercise

ACCOUNT.STANDARD_NUMBER AML.SCREENING_REQUIRED EPA.NO_INTEREST EPA.BALANCE_CAP EPA.FUNDING_CAP_30D EPA.PERMITTED_OPERATION EPA.ADDITIONAL_CREDENTIALS RECORDS.RETENTION_YEARS RECORDS.INCLUDES_REJECTED AGENT.PERMITTED_ACTIVITY SIPARD.DIRECT_PARTICIPANT_HAS_CB_ACCOUNT

pagos-al-instante-dollarsA dollar transfer through Pagos al Instante, converted by the originating bank

Two things the Central Bank says about Pagos al Instante that no scenario had exercised yet: a transfer in dollars needs no correspondent bank, and where the beneficiary's account is held in another currency the originating institution may convert, so that the beneficiary is credited in the currency of their own account. A customer of the strict legacy bank holds dollars and pays a customer of the permissive digital bank who holds pesos. The originating bank converts, records the conversion with the transaction as Arts. 41-42 require of the ten-year record, and instructs a peso order that settles in the LBTR - which settles in national and foreign currency alike (Art. 56), which is exactly why no correspondent is needed. The rates are Lab indicative figures, deliberately round and deliberately fictitious (assumption A-21). Nothing in this repository uses a published rate.

Process: 6.2 Electronic funds transfers - Pagos al Instante BCRD in dollars: no correspondent, and conversion by the originating institution when the beneficiary account is in another currency · Seed: finlab-pai-fx-2026

Variants

  • dollars-to-dollars - Dollars into a dollar account, with nothing to convert. The other half of the same statement. When the beneficiary already holds dollars there is nothing to convert, and still no correspondent: the order settles gross in the LBTR's dollar leg.
  • correspondent-must-fail - A bank that insists on a correspondent for dollars. The misconfiguration switch, in the shape the repository already uses for Art. 81: a bank configured to route dollar transfers through a correspondent is refused, the rule fails by name, and the refusal is retained in the record.

Rules it claims to exercise

PAI.USD_NO_CORRESPONDENT PAI.ORIGINATOR_CONVERTS FX.CONVERSION_RECORDED PAI.FINAL_CREDIT PAI.OPERATING_WINDOW PAI.FIXED_FEE_ONLY PAI.NO_DEDUCTION_BY_RECEIVING_BANK LBTR.SETTLEMENT_CURRENCY TRANSFER.NO_CHARGE_TO_BENEFICIARY RECORDS.RETENTION_YEARS RECORDS.INCLUDES_REJECTED

pagos-al-instantePagos al Instante BCRD - eight minutes, and the window that closes at four

Pagos al Instante BCRD runs on the LBTR and credits the beneficiary finally within eight minutes. It is available seven days a week from 07:00 to 23:00 local time, with a pause on weekdays between 16:00 and 18:30, and an order given outside that schedule becomes effective at 08:00 on the NEXT BUSINESS DAY - «se hacen efectivos a las 8:00 a.m. del siguiente dia laborable», BCRD Pagos al Instante page. The base run sends one transfer inside the window on a Tuesday morning and measures the credit. The variants send one into the weekday pause, one after 23:00, and one on a Friday night that has to wait the whole weekend - and watch the simulated Central Bank hold each of them, raising a finding on the window rule as it does, because the instruction did arrive outside it.

Process: 6.2 Electronic funds transfers - Pagos al Instante BCRD with the eight-minute credit, the 07:00-23:00 window, and the deferral to 08:00 on the next business day · Seed: finlab-pai-2026

Variants

  • weekday-pause - An order given during the weekday pause waits for the next business morning
  • after-hours - An order given after 23:00 becomes effective at 08:00 the next business day
  • friday-night-waits-for-monday - A Friday-night order waits the whole weekend, because the page says business day. The correction that made this variant worth writing. A generic "next instant the window opens" would have executed this on Saturday at 07:00; the BCRD page says «el siguiente dia laborable», so it executes on MONDAY at 08:00. Friday 13 March 2026 at 23:30 local becomes Monday 16 March at 08:00 local, which is 12:00Z.

Rules it claims to exercise

PAI.FINAL_CREDIT PAI.OPERATING_WINDOW PAI.FIXED_FEE_ONLY PAI.NO_DEDUCTION_BY_RECEIVING_BANK LBTR.THIRD_PARTY_CREDIT TRANSFER.NO_CHARGE_TO_BENEFICIARY

sgpi-instant-aliasSGPI instant payment addressed by alias

A customer of the strict legacy bank pays a customer of the permissive digital bank through the simulated Sistema de Gestion de Pagos Instantaneos, addressing the beneficiary by alias. The run checks that the payment is final inside ten seconds, that both parties are notified, that the alias resolved through the Central Bank's directory, and that both institutions are registered participants as Art. 61 numeral I requires. It is run at 03:00 on a Sunday on purpose: the SGPI has no operating window.

Process: 6.2 Electronic funds transfers - SGPI with the ten-second credit, alias resolution and 24/7/365 · Seed: finlab-sgpi-2026

Variants

  • unregistered-beneficiary-alias - The alias is not in the directory. An instant payment addressed to an alias nobody registered must fail cleanly.

Rules it claims to exercise

SGPI.FINAL_CREDIT SGPI.AVAILABILITY SGPI.MANDATORY_PARTICIPATION SGPI.NOTIFY_BOTH_PARTIES SGPI.ALIAS_ADDRESSING SIPARD.SGPI_MANAGED_BY_CENTRAL_BANK SIPARD.DIRECT_PARTICIPANT_HAS_CB_ACCOUNT TRANSFER.NO_CHARGE_TO_BENEFICIARY ACCOUNT.STANDARD_NUMBER

Running a whole scenario

# A whole process, end to end, from one call: onboarding at a strict institution,
# with the five variants that make it interesting.
export FINLAB="https://ecosystem.financial"

# what is on offer, and what each one claims to exercise
curl -s -H "x-lab-api-key: $FINLAB_API_KEY" "$FINLAB/v1/scenarios" | jq '.[] | {id, title, variants: [.variants[].id]}'

# the base run
curl -s -X POST "$FINLAB/v1/runs" \
  -H "x-lab-api-key: $FINLAB_API_KEY" -H 'content-type: application/json' \
  -d '{ "scenario": "onboarding-account-opening" }' | jq '{id, passed, summary}'

# the same scenario with the applicant who breaches the funding cap, on your own seed,
# so the run is reproducible by anybody you hand the seed to
curl -s -X POST "$FINLAB/v1/runs" \
  -H "x-lab-api-key: $FINLAB_API_KEY" -H 'content-type: application/json' \
  -d '{ "scenario": "onboarding-account-opening", "variant": "cap-reached", "seed": "our-team-2026-09-08" }' \
  | jq '{id, passed}'

# the report, in JSON and rendered as Markdown
RUN=$(curl -s -H "x-lab-api-key: $FINLAB_API_KEY" "$FINLAB/v1/runs" | jq -r '.[0].id')
curl -s -H "x-lab-api-key: $FINLAB_API_KEY" "$FINLAB/v1/runs/$RUN" | jq '.findings[] | select(.status=="fail")'
curl -s -H "x-lab-api-key: $FINLAB_API_KEY" "$FINLAB/v1/runs/$RUN/report.md" > report.md

8Rule catalogue

76 rules, catalogue version 2026.09.05. Every one of them cites the article it executes, the instrument the article belongs to, the resolution that fixed its value and the date of that resolution. A rule that does not carry all four fails to load - this is enforced in the loader, not merely asked for.

Two rules carry no article of the Reglamento at all, and say so in the article field itself: one Lab control and one governance rule. Several more state in their source exactly which half is the Reglamento's and which half is ours. A threshold with an article beside it that the article does not carry is a fabricated regulatory fact, and this catalogue is built so that one cannot be written by accident.

13 rules are flagged «pending re-check». They come from IN-36-023 and IN-36-024, both version 01 of 30 July 2021, which cross-reference the Reglamento of 29 January 2021 that the Segunda Resolución of 28 August 2025 superseded. The rules are live: they load, they are evaluated, and they produce findings. The flag refuses to let the Lab present them as settled, and it travels onto every finding they produce. IN-36-005 is version 03 of 9 April 2026 and cites the same Reglamento as the rest of the catalogue, so nothing taken from it carries the flag.

When a value changes - the Junta Monetaria adjusts a cap each January, and the high-value threshold is CPI-adjusted each year - it changes in one place, and the catalogue version changes with it.

Account numbering 1

ACCOUNT.STANDARD_NUMBERNovena Resolucion, 18 November 2010major

Accounts are numbered to the regional standardized account number adopted in 2010. The Lab uses an account number of the same shape with an LB prefix and ISO 7064 mod 97-10 check digits so it can never be mistaken for a real account.

Article
Novena Resolucion, 18 November 2010
Instrument
Novena Resolucion de la Junta Monetaria
Resolution
Novena Resolucion de la Junta Monetaria
Date
2010-11-18
Check
must_be_true
Parameter
account_number_valid
Value
true
Source
Novena Resolucion, 18 November 2010; field layout is Lab assumption A-02

Agents 1

AGENT.PERMITTED_ACTIVITYArt. 26-27major

Enrol users, fund accounts, pay out cash, show balances and deliver cards.

Article
Art. 26-27
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_member
Parameter
agent_activity
Value
["enrol","fund","cash-out","balance","card-delivery"]
Source
Reglamento Arts. 26-27

Prevention of money laundering 2

AML.SCREENING_REQUIREDArt. 43-44major

Obligations under Ley 155-17 apply to payment-service providers and participants; records must be available to supervisors.

Article
Art. 43-44
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
screening_performed
Value
true
Source
Reglamento Art. 43-44; Ley 155-17
AML.TRANSACTION_MONITORINGArt. 43-44critical

Anti-money-laundering obligations under Ley 155-17 apply to payment-service providers and participants, and their records must be available to the supervisors. A run that claims monitoring must show what was reviewed: the movements of the institutions and the machine transactions of the networks, refusals included.

Article
Art. 43-44
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
monitoring_reviewed_the_movements
Value
true
Source
Reglamento Arts. 43-44 (Ley 155-17 obligations, and records at the supervisors' disposal). The article requires the obligation and the availability of the records; it prescribes no detection pattern and no threshold. The patterns the Lab looks for, and every number in them, are Lab decisions recorded as assumption A-23.

Machines 3

ATM.CARDHOLDER_VERIFICATIONLab controlcritical

No withdrawal at a machine is authorized until the issuer has verified the holder: a PIN on the card, a biometric check through the identity entity, or an order the holder already authenticated on the phone. This is a Lab control, not an article of the Reglamento; the Reglamento's own requirement on this flow is that every transaction, including the refused ones, is recorded (Art. 41).

Article
Lab control
Instrument
CEMI Financial Innovation Lab governance
Resolution
Plan approved by Carlos Miranda Levy
Date
2026-09-04
Check
must_be_true
Parameter
cardholder_verified
Value
true
Source
Lab control, not a regulatory statement. The number of PIN attempts before a card is blocked is assumption A-19.
Notes
Catalogued so a run reports it next to the articles it does execute. Nothing in the sources read for the plan states a cardholder-verification obligation for ATM transactions; if the instructivo for administrators of payment systems does, this rule is rewritten with its citation.
ATM.CARDLESS_ORDER_SINGLE_USEArt. 78 SIVcritical

An order started on the phone and finished at the machine may be redeemed exactly once and only inside its validity. Art. 78 numeral IV requires the QR that carries it to hold the data needed to initiate a payment order; that the order is single-use and time-limited is a Lab control.

Article
Art. 78 SIV
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
order_redeemable_once_within_validity
Value
true
Source
Reglamento Art. 78 numeral IV for the QR; the single-use and time-limit controls are Lab decisions (assumption A-20).
ATM.DEPOSIT_DISCREPANCY_RECORDEDArt. 41-42major

A deposit at a machine credits what the machine recognized. Where that differs from what was declared, the difference is recorded as an adjustment, because the record of every transaction must include adjustments and be retained for ten years.

Article
Art. 41-42
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
recognition_discrepancy_recorded
Value
true
Source
Reglamento Arts. 41-42; the recognition model itself is assumption A-20.

Minimum capital 3

CAPITAL.SYSTEM_ADMINISTRATOR_AND_ACQUIRERTitulos II-Vinformational

RD$78,866,000 minimum paid-in capital, the 2026 value.

Article
Titulos II-V
Instrument
Reglamento de Sistemas de Pago
Resolution
Quinta Resolucion de la Junta Monetaria
Date
2026-01-29
Check
manual
Parameter
minimum_paid_in_capital
Value
78866000 DOP
Source
Quinta Resolucion of 29 January 2026, adjusting the Reglamento's values by CPI
CAPITAL.EPE_SUBACQUIRER_ATM_WALLETTitulos II-Vinformational

RD$19,720,000 minimum paid-in capital, the 2026 value.

Article
Titulos II-V
Instrument
Reglamento de Sistemas de Pago
Resolution
Quinta Resolucion de la Junta Monetaria
Date
2026-01-29
Check
manual
Parameter
minimum_paid_in_capital
Value
19720000 DOP
Source
Quinta Resolucion of 29 January 2026
CAPITAL.INITIATION_PROVIDERTitulos II-Vinformational

RD$9,445,500 minimum paid-in capital, the 2026 value.

Article
Titulos II-V
Instrument
Reglamento de Sistemas de Pago
Resolution
Quinta Resolucion de la Junta Monetaria
Date
2026-01-29
Check
manual
Parameter
minimum_paid_in_capital
Value
9445500 DOP
Source
Quinta Resolucion of 29 January 2026

Cards 1

CARD.PREPAID_CAPArt. 78 SIIcritical

The same RD$79,000 cap applies to prepaid cards.

Article
Art. 78 SII
Instrument
Reglamento de Sistemas de Pago
Resolution
Quinta Resolucion de la Junta Monetaria
Date
2026-01-29
Check
max_amount
Parameter
prepaid_cap
Value
79000 DOP
Source
Reglamento Art. 78 numeral II

Claims 1

CLAIM.TYPIFICATIONIN-36-023 numeral 10 f) ivmajor Pending re-check: 2025 Reglamento

The normas de funcionamiento must provide an auditable register for the control of claims and their answers, typified as attributable to operational or technological errors of the system administrator, its participants, the acquirer or its affiliated establishments; or derived from claims made by clients to participants or to users of the payment instruments processed.

Article
IN-36-023 numeral 10 f) iv
Instrument
Instructivo para los Administradores de Sistemas de Pago o de Liquidacion de Valores
Resolution
IN-36-023 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
must_be_member
Parameter
claim_class
Value
["operational-or-technological","client-originated"]
Source
IN-36-023 p.9 numeral 10 f) iv. These are the same two classes that carry the two response deadlines of IN-36-005 numeral 36, which is why the typification lives beside them here.
Notes
IN-36-023 is version 01 of 30 July 2021 and cross-references the SUPERSEDED Reglamento of 29 January 2021 throughout. The two-class typification is unlikely to have moved, but the article numbering it sits inside has, so the rule is flagged for re-check.

Direct debit and direct credit 4

DDC.RETURN_CARRIES_REASON_CODEArt. 41; Art. 79major

An item the receiving institution cannot apply is returned to the administrator with a reason code, and the return is part of the ten-year record.

Article
Art. 41; Art. 79
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
return_has_reason_code
Value
true
Source
Reglamento Art. 41 on records; Art. 79 on settlement of cycle results
Notes
The reason-code list itself is a Lab convention (assumption A-04) until the instructivo for administrators of payment systems is read in full.
DDC.CYCLE_ON_BUSINESS_DAYArt. 79major

Clearing cycles of the direct debit and direct credit systems run on business days.

Article
Art. 79
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
cycle_ran_on_business_day
Value
true
Source
Reglamento Art. 79; the calendar itself is Lab configuration (assumption A-01)
DDC.CREDITING_TIME_IS_DECLARED_NOT_FIXEDIN-36-023 numeral 10 c)critical Pending re-check: 2025 Reglamento

The normas de funcionamiento of every payment system must state the moment at which transfers of funds or securities are accepted by the system and become irrevocable, and the time to credit those funds to the final beneficiary of payment orders after acceptance. The Central Bank fixes no universal figure; the obligation is to declare one.

Article
IN-36-023 numeral 10 c)
Instrument
Instructivo para los Administradores de Sistemas de Pago o de Liquidacion de Valores
Resolution
IN-36-023 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
must_be_true
Parameter
system_declares_crediting_time_and_irrevocability_instant
Value
true
Source
IN-36-023 p.9 numeral 10 c). This closes the question the spec asked of this document: the crediting time is DELEGATED to each administrator, so the checkable rule is the obligation to declare it. The simulated administrator declares its own and the run records what it declared, which is exactly the shape assumption A-03 gave the parameter.
DDC.CLAIM_RECEPTION_YEARSIN-36-023 numeral 10 f) iiimajor Pending re-check: 2025 Reglamento

The normas de funcionamiento must provide a claim-reception period of up to four years, counted from the moment the user becomes aware of the event giving rise to the claim.

Article
IN-36-023 numeral 10 f) iii
Instrument
Instructivo para los Administradores de Sistemas de Pago o de Liquidacion de Valores
Resolution
IN-36-023 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
retention
Parameter
system_claim_reception_years
Value
4 years
Source
IN-36-023 p.9 numeral 10 f) iii. The anchor - the user's knowledge - differs from the one IN-36-024 numeral 49 gives the same four years for an electronic payment account.

Electronic payment accounts 16

EPA.BALANCE_CAPArt. 78 SIIcritical

The balance of an electronic payment account may not exceed RD$79,000, the 2026 value of the cap adjusted yearly by the Junta Monetaria.

Article
Art. 78 SII
Instrument
Reglamento de Sistemas de Pago
Resolution
Quinta Resolucion de la Junta Monetaria
Date
2026-01-29
Check
max_amount
Parameter
balance_cap
Value
79000 DOP
Source
Reglamento Art. 78 numeral II; value set by the Quinta Resolucion of 29 January 2026
Notes
Re-check every January when the Junta Monetaria adjusts the Reglamento's values.
EPA.FUNDING_CAP_30DArt. 78 SIIcritical

Funding of an electronic payment account may not exceed RD$79,000 within any 30-day window.

Article
Art. 78 SII
Instrument
Reglamento de Sistemas de Pago
Resolution
Quinta Resolucion de la Junta Monetaria
Date
2026-01-29
Check
max_amount
Parameter
funding_cap_30_days
Value
79000 DOP
Source
Reglamento Art. 78 numeral II; value set by the Quinta Resolucion of 29 January 2026
EPA.NO_INTERESTArt. 19major

The balance equals the nominal value received, bears no interest and is refundable on demand.

Article
Art. 19
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_false
Parameter
interest_accrued
Value
false
Source
Reglamento Art. 19-25
EPA.PERMITTED_OPERATIONArt. 20major

Cash withdrawal, direct credit, direct debit, POS, ATM withdrawal, e-commerce, airtime and data top-ups, bill payment, inbound remittances and social subsidies.

Article
Art. 20
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_member
Parameter
operation
Value
["cash-withdrawal","direct-credit","direct-debit","pos","atm-withdrawal","e-commerce","top-up","bill-payment","inbound-remittance","social-subsidy"]
Source
Reglamento Art. 20
EPA.ADDITIONAL_CREDENTIALSArt. 19 SVminor

An account holder may hold additional credentials on the same balance, each with its own limits.

Article
Art. 19 SV
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
manual
Parameter
credential_limits_enforced
Value
true
Source
Reglamento Art. 19 numeral V
EPA.FUNDING_AVAILABLE_AFTER_SETTLEMENTIN-36-024 numeral 23 a)critical Pending re-check: 2025 Reglamento

Availability in the electronic payment account of funding made through other payment instruments carrying deferred crediting must occur at the latest two hours after its settlement, when credited through electronic payment instruments.

Article
IN-36-024 numeral 23 a)
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
max_duration
Parameter
epa_funding_availability_after_settlement
Value
2 h
Source
IN-36-024 p.11 numeral 23 a). The reference instant is SETTLEMENT of the funding instrument, not the instruction - the instructivo says "luego de su liquidacion" - which is also the anchor assumption A-11 chose for the Art. 57 four minutes, now supported by analogy rather than only by the Lab's reading.
EPA.FUNDING_AVAILABLE_AFTER_CHEQUEIN-36-024 numeral 23 b)critical Pending re-check: 2025 Reglamento

Availability in the electronic payment account must occur at the latest thirty minutes after the cheque is credited to the bank account of the electronic payment entity providing the service.

Article
IN-36-024 numeral 23 b)
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
max_duration
Parameter
epa_funding_availability_after_cheque
Value
30 m
Source
IN-36-024 p.11 numeral 23 b). The reference instant is the cheque landing in the EPE's OWN bank account, which is a different instant from the cheque being deposited. The SCC that would clear the cheque is Phase 3, so the run supplies that instant explicitly.
EPA.CAP_WINDOW_IS_CALENDAR_DAYSIN-36-024 numeral 18 b)critical Pending re-check: 2025 Reglamento

The technological solution must show the holder the headroom remaining against the issuance or funding limit permitted within the 30 calendar-day period in which the account currently sits, and must notify the user when that ceiling is reached.

Article
IN-36-024 numeral 18 b)
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
must_equal
Parameter
epa_cap_window_calendar_days
Value
30 calendar days
Source
IN-36-024 p.10 numeral 18 b). This settles the UNIT of assumption A-12 - calendar days, not elapsed simulated hours - and the EPE now counts the window on local dates. It does NOT settle rolling versus fixed anchoring: "el periodo de 30 dias calendario en que se encuentre" reads more naturally as a fixed period, and A-12 stays open on that half.
EPA.FUNDING_OVER_CAP_REJECTEDIN-36-024 numeral 19 d)critical Pending re-check: 2025 Reglamento

The technological solution must have the capacity to reject the funding of accounts when it exceeds the limit established for the user.

Article
IN-36-024 numeral 19 d)
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
must_be_true
Parameter
epa_over_cap_funding_rejected
Value
true
Source
IN-36-024 p.11 numeral 19 d). Evaluated where the EPE refuses: the observed value is whether the funding was actually rejected once EPA.BALANCE_CAP or EPA.FUNDING_CAP_30D failed, which turns a cap breach from a finding into a refusal.
EPA.NO_OVERDRAFTIN-36-024 numeral 20critical Pending re-check: 2025 Reglamento

The payment instrument shall not permit overdrafts where funds are insufficient to carry out an operation; in that case the payment order shall be rejected.

Article
IN-36-024 numeral 20
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
must_be_false
Parameter
epa_overdraft_permitted
Value
false
Source
IN-36-024 p.11 numeral 20; the same numeral also forbids a minimum balance
EPA.FLOAT_FULLY_BACKED_AT_CENTRAL_BANKIN-36-024 numeral 26 a) y c)critical Pending re-check: 2025 Reglamento

Before managing electronic payment accounts the electronic payment entity must hold in its Central Bank current account the funds corresponding to the account to be managed, provisioned by electronic funds transfer, and must keep account reconciliations so that the funds held for its users correspond to the balance in its Central Bank current account and the resources previously deposited to guarantee the managed balances.

Article
IN-36-024 numeral 26 a) y c)
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
must_be_true
Parameter
epa_float_covers_managed_balances
Value
true
Source
IN-36-024 p.12 numeral 26 opening, a) and c). This is a full-reserve invariant the Lab's reconciliation layer can assert directly, and it is stronger than the network-wide mirror-sum-zero check that assumption A-14 describes.
EPA.DAILY_REPORT_TO_CENTRAL_BANKIN-36-024 numeral 26 d)major Pending re-check: 2025 Reglamento

The electronic payment entity must report daily to the Central Bank, through the mechanisms it provides, information on the enablement of electronic payment accounts, the funding and the withdrawals made by its users, and the total balance held in their favour.

Article
IN-36-024 numeral 26 d)
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
must_be_true
Parameter
epa_daily_report_submitted
Value
true
Source
IN-36-024 p.12 numeral 26 d). The mechanism the Central Bank provides is not described, so the Lab sends the report over the bus to the simulated Central Bank and reports the four figures the numeral names, and nothing more.
EPA.CLAIM_RECEPTION_YEARSIN-36-024 numeral 49major Pending re-check: 2025 Reglamento

Users of an electronic payment account may bring claims before the electronic payment entity within a period of no more than four years, counted from the moment the event giving rise to the claim occurs.

Article
IN-36-024 numeral 49
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
retention
Parameter
epa_claim_reception_years
Value
4 years
Source
IN-36-024 p.19 numeral 49. Note the anchor differs from IN-36-023 numeral 10 f) iii, which runs the same four years from the user's KNOWLEDGE of the event rather than from the event. The two documents are not reconciled and the Lab does not reconcile them.
EPA.CLAIM_RESPONSE_DAYSIN-36-024 numeral 49major Pending re-check: 2025 Reglamento

The entity must have agile and reasonable claim-reception mechanisms and must answer claims within a maximum of thirty calendar days from the date of receipt.

Article
IN-36-024 numeral 49
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
max_count
Parameter
epa_claim_response_calendar_days
Value
30 calendar days
Source
IN-36-024 p.19 numeral 49, continuing on p.20
EPA.NO_FEE_FOR_CLAIMSIN-36-024 numeral 47 e) y f)major Pending re-check: 2025 Reglamento

In its relationship with users the electronic payment entity shall not charge commissions or fees for claims made, and shall immediately rectify the situations giving rise to a claim where the outcome so determines.

Article
IN-36-024 numeral 47 e) y f)
Instrument
Instructivo para las Entidades de Pago Electronico y Cuentas de Pago Electronico
Resolution
IN-36-024 version 01, aprobado por el Gobernador del Banco Central
Date
2021-07-30
Check
must_equal
Parameter
epa_claim_fee_minor
Value
0 DOP
Source
IN-36-024 p.19 numeral 47 e) and f)
EPA.FLOAT_ONLY_AT_CENTRAL_BANKArt. 22critical

The funds an electronic payment entity holds against the balances it manages may be kept ONLY in its current account at the Central Bank, or in securities issued by the Central Bank or the Ministerio de Hacienda pledged in favour of the Central Bank. They may not be held in a commercial bank, and they may not be invested in anything else.

Article
Art. 22
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_member
Parameter
epa_float_placement
Value
["central-bank-current-account","pledged-bcrd-securities","pledged-hacienda-securities"]
Source
Reglamento Art. 22, verified on 2026-09-05. This is the placement rule and it is stronger than the coverage rule: IN-36-024 numeral 26 requires the float to COVER the managed balances, and Art. 22 says WHERE it may sit. A float fully covering its balances but held at a commercial bank satisfies the first and breaches the second.
Notes
The pledged-securities placements are catalogued and unexercised: the ecosystem has no securities settlement system before Phase 3, so the only placement a run can take is the Central Bank current account.

Foreign currency 1

FX.CONVERSION_RECORDEDArt. 41-42major

A conversion performed on a transfer is part of the transaction record: the currencies, the rate applied, the amount debited and the amount credited are retained for ten years with the transaction they belong to, and are available to the account holder and to the supervisors.

Article
Art. 41-42
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
conversion_recorded
Value
true
Source
Reglamento Arts. 41-42. The rates themselves are Lab configuration and are deliberately fictitious (assumption A-21); no published rate is used anywhere in this repository.

Payment initiation 1

INITIATION.NEVER_HOLDS_FUNDSArt. 4 mm, 38-40critical

Initiation of payment orders on a user's account happens by verifiable consent through secure interfaces; the provider never holds the funds.

Article
Art. 4 mm, 38-40
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_false
Parameter
initiator_held_funds
Value
false
Source
Reglamento Art. 4 mm and Arts. 38-40

Lab governance 2

LAB.NOT_AMBIENTE_DE_PRUEBAArt. 83critical

The simulation involves no real providers and no real external users, so it does not fall under the no-objection regime of Art. 83. A run is never a substitute for the Central Bank's no objection; its report is evidence for a request, nothing more.

Article
Art. 83
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
run_involves_only_simulated_counterparts
Value
true
Source
Reglamento Art. 83; plan section 10
LAB.SIMULATOR_CARRIES_LAB_NAMEgovernancecritical

No simulator presents itself as the entity it is modelled after. No real credentials, keys, BINs, routing identifiers, aliases or certificates exist anywhere in a run.

Article
governance
Instrument
CEMI Financial Innovation Lab governance
Resolution
Plan approved by Carlos Miranda Levy
Date
2026-09-04
Check
must_be_true
Parameter
simulator_uses_lab_identity
Value
true
Source
plan section 10

LBTR: settlement, priority, finality 14

LBTR.THIRD_PARTY_CREDITArt. 57critical

A credit in favour of a third party must be posted within four minutes of the receiving participant's account being affected.

Article
Art. 57
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
max_duration
Parameter
third_party_credit_minutes
Value
4 m
Source
Reglamento Art. 57
LBTR.IRREVOCABLE_ONCE_SETTLEDArt. 66critical

An order settled in the LBTR is irrevocable; only a queued order may be revoked.

Article
Art. 66
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_false
Parameter
revocation_accepted_after_settlement
Value
false
Source
Reglamento Art. 66; BCRD Sistema LBTR page
LBTR.REVOCABLE_WHILE_QUEUEDArt. 66major

While an order sits in the LBTR queue and has not settled, the submitting participant may revoke it.

Article
Art. 66
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
revocation_accepted_while_queued
Value
true
Source
Reglamento Art. 66; BCRD Sistema LBTR page
LBTR.SETTLEMENT_CURRENCYBCRD Sistema LBTRmajor

The real-time gross settlement system settles continuously in Dominican pesos, US dollars and euros.

Article
BCRD Sistema LBTR
Instrument
BCRD published description of the LBTR
Resolution
BCRD Sistema LBTR page
Date
2026-09-04
Check
must_be_member
Parameter
settlement_currency
Value
["DOP","USD","EUR"]
Source
BCRD Sistema LBTR page
LBTR.HIGH_VALUE_THRESHOLDIN-36-005 numeral 69critical

Electronic funds transfers exceeding RD$15,800,000.00, or the equivalent in foreign currency, are high-value transfers and must necessarily settle through the Central Bank's LBTR. Lower amounts may go through the LBTR or through any authorized payment system. The figure is adjusted annually by the year-on-year change in the Consumer Price Index published by the Central Bank, so it is re-checked each year exactly as the 2026 Junta Monetaria values are.

Article
IN-36-005 numeral 69
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
max_amount
Parameter
non_lbtr_transfer_amount
Value
15800000 DOP
Source
IN-36-005 p.22 numeral 69 and Parrafos I-II. Evaluated on every payment routed on a rail OTHER than the LBTR proper - an SGPI instant payment and a Pagos al Instante order - which is where the obligation bites. CPI-adjusted annually; re-check each year.
Notes
The equivalence in foreign currency is stated by the instructivo but the conversion basis is not; a run in USD or EUR therefore does not evaluate this rule and says so.
LBTR.PRIORITY_RANGE_PARTICIPANTIN-36-005 numeral 22 Parrafo Imajor

The LBTR offers participants 80 priorities, 20 being the highest and 99 the lowest. Assigning a priority is optional.

Article
IN-36-005 numeral 22 Parrafo I
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
within_range
Parameter
participant_priority
Value
[20,99]
Source
IN-36-005 p.13 numeral 22 Parrafo I
LBTR.PRIORITY_DEFAULTIN-36-005 numeral 22 Parrafos I-IImajor

Where the originating participant assigns no priority, the LBTR assigns priority 98. The same default applies to a securities-settlement delivery-versus-payment instruction whose administrator set none.

Article
IN-36-005 numeral 22 Parrafos I-II
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
must_equal
Parameter
default_priority
Value
98
Source
IN-36-005 p.13 numeral 22 Parrafos I y II
LBTR.PRIORITY_RESERVED_TO_CENTRAL_BANKIN-36-005 numeral 22 Parrafo IIImajor

The Central Bank holds, exclusively and permanently, the priority range 0 to 14. No participant instruction may carry a priority inside it.

Article
IN-36-005 numeral 22 Parrafo III
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
must_be_false
Parameter
participant_instruction_uses_reserved_priority
Value
false
Source
IN-36-005 p.13 numeral 22 Parrafo III
LBTR.PRIORITY_RANGE_DVPIN-36-005 numeral 22 Parrafo IIminor

Funds-transfer instructions sent by the administrator of a securities settlement system under delivery-versus-payment may be assigned a priority in the range 15 to 98.

Article
IN-36-005 numeral 22 Parrafo II
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
within_range
Parameter
dvp_priority
Value
[15,98]
Source
IN-36-005 p.13 numeral 22 Parrafo II. Catalogued and unexercised: no securities settlement system exists in the ecosystem before Phase 3, so nothing sends a DvP instruction yet.
LBTR.SETTLEMENT_PRELATIONIN-36-005 numeral 21major

Settlement precedence, highest to lowest, is: Central Bank operations debiting participant accounts; Sistema Electronico de Subastas operations; SGPI results; cheque clearing (SCC) results; Plataforma Cambiaria BCRD results; results of deferred net settlement systems run by other administrators; and participant funds transfers for own or third-party account.

Article
IN-36-005 numeral 21
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
must_be_member
Parameter
settlement_prelation
Value
["central-bank-debit","auction-css","sgpi-results","cheque-clearing-scc","plataforma-cambiaria","deferred-net-settlement","participant-transfer"]
Source
IN-36-005 p.12 numeral 21 a-g. The ORDER of the list is the rule, and the queue in packages/central-bank/src/central-bank.ts drains in exactly this order, then by priority, then by time of submission. Two of the seven classes have no actor in the ecosystem yet - the auction system and the Plataforma Cambiaria - and the SCC arrives in Phase 3.
LBTR.QUEUE_ON_INSUFFICIENT_FUNDSIN-36-005 numerales 16 y 23major

The LBTR settles instructions one by one on their value date provided the originating participant has funds in its Central Bank current account. On an insufficient balance the instruction queues, in state Listo, awaiting sufficient funds.

Article
IN-36-005 numerales 16 y 23
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
must_be_true
Parameter
insufficient_funds_queues_not_rejects
Value
true
Source
IN-36-005 p.10 numeral 16, p.13 numeral 23
LBTR.REVOCABLE_UNTIL_SETTLEDIN-36-005 numeral 18major

Funds-transfer instructions may be cancelled by the participant that made them or by the Central Bank, at any time, so long as they have not settled in the LBTR. This refines LBTR.REVOCABLE_WHILE_QUEUED, which models only the participant's own revocation.

Article
IN-36-005 numeral 18
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
must_be_true
Parameter
central_bank_may_cancel_unsettled_order
Value
true
Source
IN-36-005 p.11 numeral 18
LBTR.END_OF_DAY_QUEUE_FLUSHIN-36-005 numeral 25major

At the hour set in the daily operating cycle, and before closing LBTR operations, the Central Bank may remove from the queue instructions dated for settlement that day which the issuer has not already cancelled. That removal is deemed equivalent to revocation by the issuing participant, and the Central Bank bears no liability for the consequences.

Article
IN-36-005 numeral 25
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
must_be_true
Parameter
queued_order_flushed_at_close_is_revoked
Value
true
Source
IN-36-005 p.13 numeral 25 and Parrafo. The HOUR is set by the daily operating cycle, which the instructivo defers to a Circular of the Gerencia the Lab has not read (numeral 95), so the flush is an operation the scenario invokes rather than a clock event the Lab invents.
LBTR.ORDER_STATEIN-36-005 numeral 19major

The state of a funds-transfer instruction in the LBTR is one of Almacenado, Anulado, Ingresado, Liquidado, Listo, Pendiente or Rechazado.

Article
IN-36-005 numeral 19
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
must_be_member
Parameter
lbtr_order_state
Value
["Almacenado","Anulado","Ingresado","Liquidado","Listo","Pendiente","Rechazado"]
Source
IN-36-005 p.11 numeral 19 a-g. The simulator's own four statuses map onto these: queued is Listo, settled is Liquidado, revoked is Anulado, rejected is Rechazado. The mapping is the Lab's, the vocabulary is the instructivo's.

Net settlement 2

NET.SETTLES_IN_LBTRArt. 79critical

The results of each clearing cycle of the electronic-instrument systems settle in the real-time gross settlement system.

Article
Art. 79
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
cycle_settled_in_lbtr
Value
true
Source
Reglamento Art. 79; Art. 67 for deferred-net finality
NET.DEFERRED_FINALITYArt. 67major

A deferred-net system carries its own irrevocability and finality rules for the settled net result.

Article
Art. 67
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
net_result_final_once_settled
Value
true
Source
Reglamento Art. 67

Pagos al Instante BCRD 10

PAI.FINAL_CREDITBCRD Pagos al Instantecritical

A Pagos al Instante BCRD transfer reaches the beneficiary as a final credit within eight minutes.

Article
BCRD Pagos al Instante
Instrument
BCRD published description of Pagos al Instante BCRD
Resolution
BCRD Pagos al Instante BCRD page
Date
2026-09-04
Check
max_duration
Parameter
final_credit_minutes
Value
8 m
Source
BCRD Pagos al Instante BCRD page; runs on the LBTR
PAI.OPERATING_WINDOWBCRD Pagos al Instantemajor

Available seven days a week from 07:00 to 23:00 local time, with a pause on weekdays between 16:00 and 18:30. An order given outside that schedule is not refused: it becomes effective at 08:00 on the next business day (PAI.DEFERRED_TO_NEXT_BUSINESS_DAY).

Article
BCRD Pagos al Instante
Instrument
BCRD published description of Pagos al Instante BCRD
Resolution
BCRD Pagos al Instante BCRD page
Date
2026-09-04
Check
within_window
Parameter
instruction_instant
Value
"07:00-23:00 with a weekday pause 16:00-18:30"
Source
BCRD Pagos al Instante page, https://www.bancentral.gov.do/a/d/2665-descripcion. Verified against the page on 2026-09-05.
PAI.DEFERRED_TO_NEXT_BUSINESS_DAYBCRD Pagos al Instantemajor

Orders instructed outside the Pagos al Instante schedule «se hacen efectivos a las 8:00 a.m. del siguiente dia laborable»: they become effective at 08:00 on the NEXT BUSINESS DAY. A Friday-night order therefore becomes effective on Monday morning, not on Saturday.

Article
BCRD Pagos al Instante
Instrument
BCRD published description of Pagos al Instante BCRD
Resolution
BCRD Pagos al Instante BCRD page
Date
2026-09-05
Check
must_equal
Parameter
deferred_execution_local_time
Value
"08:00"
Source
BCRD Pagos al Instante page, https://www.bancentral.gov.do/a/d/2665-descripcion, read on 2026-09-05: «se hacen efectivos a las 8:00 a.m. del siguiente dia laborable». This CORRECTS the Lab's earlier reading, which deferred to 07:00 on the next calendar day - two mistakes in one: the wrong hour, and a calendar day where the page says a business day.
Notes
The page says «fuera del horario» without distinguishing the after-hours case from the weekday pause, so the Lab applies the same deferral to both. Treating the 16:00-18:30 pause as «fuera del horario» is the Lab's reading and not the page's words; see assumption A-10.
PAI.FIXED_FEE_ONLYBCRD Pagos al Instantemajor

The fee for a Pagos al Instante transfer is a fixed amount; a percentage of the transferred amount is not permitted.

Article
BCRD Pagos al Instante
Instrument
BCRD published description of Pagos al Instante BCRD
Resolution
BCRD Pagos al Instante BCRD page
Date
2026-09-04
Check
must_be_true
Parameter
fee_is_fixed_amount
Value
true
Source
BCRD Pagos al Instante BCRD page
PAI.NO_DEDUCTION_BY_RECEIVING_BANKBCRD Pagos al Instantecritical

The beneficiary's institution may not deduct anything from the amount transferred.

Article
BCRD Pagos al Instante
Instrument
BCRD published description of Pagos al Instante BCRD
Resolution
BCRD Pagos al Instante BCRD page
Date
2026-09-04
Check
must_be_false
Parameter
receiving_institution_deducted
Value
false
Source
BCRD Pagos al Instante BCRD page; see also Reglamento Art. 81
PAI.FEE_REVERSED_ON_MISSED_DEADLINEIN-36-005 numeral 34 Parrafomajor

Where the transfer or payment is not applied within the established period for reasons attributable to the originating or the receiving entity, the originating client receives an automatic reversal of the fee charged, borne by the entity in breach.

Article
IN-36-005 numeral 34 Parrafo
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
must_be_true
Parameter
fee_reversed_when_deadline_missed
Value
true
Source
IN-36-005 p.16 numeral 34 Parrafo. The "established period" is the eight minutes of PAI.FINAL_CREDIT, whose own anchor remains assumption A-10 - so the consequence is the instructivo's and the deadline it hangs on is still partly the Lab's.
PAI.CLAIM_RESPONSE_OPERATIONALIN-36-005 numeral 36 a)major

Where a participant makes a Pagos al Instante claim against another participant, the latter answers within up to two business days for requests attributable to the participants' own operational or technological errors.

Article
IN-36-005 numeral 36 a)
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
max_count
Parameter
claim_response_business_days
Value
2 business days
Source
IN-36-005 p.17 numeral 36 a). Counted in BUSINESS days by the run's own calendar, which is Lab configuration (assumption A-01), so the count is only as right as the holiday list.
PAI.CLAIM_RESPONSE_CLIENTIN-36-005 numeral 36 b)major

The same claim mechanism allows up to five business days for requests arising from claims made by the client.

Article
IN-36-005 numeral 36 b)
Instrument
Instructivo del Sistema de Liquidacion Bruta en Tiempo Real
Resolution
IN-36-005 version 03, aprobado por el Gobernador del Banco Central
Date
2026-04-09
Check
max_count
Parameter
claim_response_business_days
Value
5 business days
Source
IN-36-005 p.17 numeral 36 b); the same calendar caveat as PAI.CLAIM_RESPONSE_OPERATIONAL
PAI.USD_NO_CORRESPONDENTBCRD Pagos al instantemajor

Transfers in United States dollars through Pagos al Instante BCRD move between participants without a correspondent bank: they settle in the LBTR, which settles in Dominican pesos, US dollars and euros.

Article
BCRD Pagos al instante
Instrument
BCRD published description of Pagos al Instante BCRD
Resolution
BCRD Pagos al instante page
Date
2026-09-04
Check
must_be_false
Parameter
correspondent_used
Value
false
Source
BCRD Pagos al instante page; BCRD Sistema LBTR page for the settlement currencies (Art. 56, national and foreign currency)
PAI.ORIGINATOR_CONVERTSBCRD Pagos al instantemajor

Where the beneficiary's account is held in a currency other than the one the order is instructed in, the originating institution may perform the conversion, and the beneficiary is credited in the currency of their own account.

Article
BCRD Pagos al instante
Instrument
BCRD published description of Pagos al Instante BCRD
Resolution
BCRD Pagos al instante page
Date
2026-09-04
Check
must_be_true
Parameter
originating_institution_converted
Value
true
Source
BCRD Pagos al instante page. Whether the conversion is a permission or an obligation is read here as a permission: the rule fires only when a conversion was actually needed.

QR 1

QR.PRESENT_AND_READArt. 78 SIVmajor

Every payment-service provider must be able to present and read a QR code carrying the data needed to initiate a payment order, to the standard the Central Bank sets by instructivo.

Article
Art. 78 SIV
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
manual
Parameter
qr_present_and_read
Value
true
Source
Reglamento Art. 78 numeral IV; the QR instructivo is pending publication

Records 2

RECORDS.RETENTION_YEARSArt. 41-42major

Providers and participants store every transaction, including rejected ones and adjustments, for ten years, with full user access and delivery to the Central Bank and supervisors without undue delay.

Article
Art. 41-42
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
retention
Parameter
retention_years
Value
10 years
Source
Reglamento Art. 41-42
RECORDS.INCLUDES_REJECTEDArt. 41major

Rejected transactions and adjustments are part of the retained record, not only settled ones.

Article
Art. 41
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
rejected_transactions_recorded
Value
true
Source
Reglamento Art. 41

SGPI instant payments 5

SGPI.FINAL_CREDITBCRD SGPI pagecritical

The Sistema de Gestion de Pagos Instantaneos credits the beneficiary finally within ten seconds of the instruction.

Article
BCRD SGPI page
Instrument
BCRD published description of the SGPI
Resolution
BCRD SGPI page
Date
2026-09-05
Check
max_duration
Parameter
final_credit_seconds
Value
10 s
Source
BCRD SGPI page, https://www.bancentral.gov.do/a/d/6142. Verified on 2026-09-05. THE TEN SECONDS ARE NOT IN THE REGLAMENTO. Arts. 60-61 establish the SGPI, its administration and who must participate in it; the ten-second parameter is published on the Central Bank's own page and nowhere in the articles. The citation was corrected on 2026-09-05, because a threshold with an article beside it that the article does not carry is exactly the fabricated regulatory fact this catalogue exists to prevent.
Notes
Where the ten seconds is measured from and to is still the Lab's reading (assumption A-09); what is settled is where the figure comes from.
SGPI.AVAILABILITYBCRD SGPI pagecritical

The SGPI operates 24/7/365; there is no operating window and no cut-off.

Article
BCRD SGPI page
Instrument
BCRD published description of the SGPI
Resolution
BCRD SGPI page
Date
2026-09-05
Check
must_be_true
Parameter
available_at_instruction_time
Value
true
Source
BCRD SGPI page, https://www.bancentral.gov.do/a/d/6142. Verified on 2026-09-05. Like the ten seconds, the 24/7/365 availability is published on the page and is not an article of the Reglamento; the citation was corrected on 2026-09-05. It is CONFIRMED independently by IN-36-005 pp.6-7 numeral 3 mm), which defines the SGPI as operating in real time, 24 hours a day, 7 days a week.
SGPI.MANDATORY_PARTICIPATIONArt. 61 SIcritical

All financial-intermediation entities, electronic-payment entities, acquirers and sub-acquirers are mandatory participants of the SGPI.

Article
Art. 61 SI
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
participant_registered_in_sgpi
Value
true
Source
Reglamento Art. 61 numeral I
SGPI.NOTIFY_BOTH_PARTIESArt. 61major

Payer and beneficiary are both notified immediately once the instant payment is credited.

Article
Art. 61
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
both_parties_notified
Value
true
Source
BCRD SGPI page; Reglamento Art. 61
SGPI.ALIAS_ADDRESSINGArt. 60-61major

An instant payment may be addressed to an alias resolved by the Central Bank's directory.

Article
Art. 60-61
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
alias_resolved
Value
true
Source
BCRD SGPI page

SIPA regional transfers 2

SIPA.OPERATING_WINDOWBCRD SIPAmajor

Regional real-time USD transfers with Costa Rica, El Salvador, Guatemala, Honduras and Nicaragua run on weekdays from 07:00 to 17:00 Dominican time.

Article
BCRD SIPA
Instrument
BCRD published description of the SIPA
Resolution
BCRD SIPA page
Date
2026-09-04
Check
within_window
Parameter
instruction_instant
Value
"weekdays 07:00-17:00"
Source
BCRD SIPA page
SIPA.ORIGINATOR_FEEBCRD SIPAmajor

A SIPA transfer carries a US$5 fee, paid by the originator.

Article
BCRD SIPA
Instrument
BCRD published description of the SIPA
Resolution
BCRD SIPA page
Date
2026-09-04
Check
must_equal
Parameter
originator_fee_usd
Value
5 USD
Source
BCRD SIPA page

SIPARD participation and interoperability 3

SIPARD.DIRECT_PARTICIPANT_HAS_CB_ACCOUNTArt. 4 zz-bbbcritical

Direct participants in the SIPARD hold current accounts at the Central Bank; indirect participants settle through a direct one.

Article
Art. 4 zz-bbb
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
has_central_bank_current_account
Value
true
Source
Reglamento Art. 4 zz-bbb; BCRD SIPARD page
SIPARD.INTEROPERABILITYArt. 10major

Every administrator of a payment system must be interoperable.

Article
Art. 10
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
manual
Parameter
administrator_is_interoperable
Value
true
Source
Reglamento Art. 10
SIPARD.SGPI_MANAGED_BY_CENTRAL_BANKArt. 62critical

The SIPARD is a public service owned exclusively by the Central Bank; SGPI management is not delegable.

Article
Art. 62
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_true
Parameter
sgpi_administrator_is_central_bank
Value
true
Source
Reglamento Art. 60, 62; Ley 183-02 Art. 27

Transfers 1

TRANSFER.NO_CHARGE_TO_BENEFICIARYArt. 81; Art. 56 SIIcritical

No charge may be applied to the beneficiary of a transfer or payment; the cost is borne by the ordering party.

Article
Art. 81; Art. 56 SII
Instrument
Reglamento de Sistemas de Pago
Resolution
Segunda Resolucion de la Junta Monetaria
Date
2025-08-28
Check
must_be_false
Parameter
charge_applied_to_beneficiary
Value
false
Source
Reglamento Art. 81 and Art. 56 numeral II

9Versioning and change policy

Three things carry a version, and they move for different reasons.

WhatWhere you read itWhen it moves
The rule catalogueruleCatalogue on /v1/health, and on every run reporta rule is added, a value is adjusted, or a citation is corrected. Dated, YYYY.MM.DD.
The OpenAPI contractinfo.version in /openapi.jsonan endpoint, a field or a response shape changes
This manualthe footer of every pageregenerated from the sources on every deploy; it cannot be older than what it documents

What the Lab will and will not do to you

  • Additive changes arrive without warning, and your integration should tolerate them: a new endpoint, a new field on a response, a new rule in the catalogue, a new scenario, a new actor on the bus. Ignore fields you do not recognise.
  • A breaking change to a request or a response is announced first, in the changelog and to every team holding a key, with the date it takes effect.
  • A regulatory value changing is not a breaking change. If the Junta Monetaria adjusts a cap, or the CPI moves the high-value threshold, the catalogue changes and your runs start failing where they used to pass. That is the ecosystem working. The rule's resolutionDate tells you which vintage you are being judged against.
  • A world reset is never done to you. Only your own team can reset your world, and an admin only on request.

Reproducibility across a change

A run report carries the rule-catalogue version, the seed, the clock mode and the fidelity tier of every actor. A run that passed under catalogue 2026.09.05 is a pass on that catalogue, and the report says so on its face. That is what lets a report be handed to a supervisor months later and still mean something precise.

10Limits and fair use

The Lab pays for this instance out of its own budget. There is no billing, no quota page and no plan to add one - what there is instead is an expectation, stated plainly.

What the instance is

ComputeA single small Cloud Run service that scales to zero. The first call after an idle period pays a cold start of a few seconds.
Your worldBuilt on your first call and kept in memory for the life of the instance. A world does not survive a redeploy or a scale-to-zero - it is rebuilt from the same seed, so the people and their documents come back, and anything you did does not. Treat a world as a working surface, and the run report as the record.
Your reportsIn the project's Firestore, and they do survive. They are the record, and the seed on them is what makes a run reproducible.
ConcurrencyA run holds a world while it executes. Several teams running at once is fine; one team firing hundreds of concurrent runs is not, and will simply be slow for that team first.

What we ask

  • Do not load-test the instance. It is not a performance rig and its timings are Lab configuration, not measurements of anything. If you want to exercise throughput, ask for a sponsored node.
  • Do not poll /v1/runs in a tight loop. A run tells you its id when it finishes; webhooks exist for the rest.
  • Do not put a real credential, a real PAN, a real document number or real personal data into this ecosystem. There is nowhere for it to go that is appropriate, everything is recorded in a trace, and nothing here is a system of record for anybody's data. This is the one limit that is not about politeness.
  • Do not present a run as an approval. See the governance section; it is short and it matters more than everything else on this page.
  • One key, one team. If a second team in your organization needs access, ask for a second key so that the two get separate worlds. Sharing a key means sharing a world, and then two teams debug each other's state.
If you hit something that feels like a limit and is not documented here, it is probably a defect. Say so on the feedback form - that is exactly what it is for.

11Support, and asking for more

Two forms, and they go to the same place

  • Request a team key - for an organization that wants to plug something in. Tell us who you are, what you would exercise and roughly when; the Lab mints a key and a world for you and hands the key over. Nothing is issued automatically, and that is on purpose.
  • Comments, suggestions, corrections and defects - including «this rule cites the wrong article», which is the single most valuable thing anybody can send us. Name the article or the document, and we will check it against the source and correct the catalogue.

By address

ForWrite to
partnerships, keys, sponsored nodespartners@cemi.ai
a leaked key, or anything security-shapedsecurity@cemi.ai
legal and governance questionslegal@cemi.ai
anything elsecontact@cemi.ai

A sponsored node

A sponsored node is an instance of the ecosystem carrying one institution's own configuration: its personality, its policies, its rates, its own private lane for its vendors and the startups it works with. The Lab's shared instance deliberately carries fictitious exchange rates and Lab thresholds, because a shared instance is the wrong place for a real table. A sponsored node is the right place, and it is the mechanism by which a bank, a processor or a regulator gets an ecosystem shaped like their own.

Ask through the key-request form, saying so in the intended-use field, or write to partners@cemi.ai.

The Lab

The Virtual Financial Ecosystem Simulation is the fourth proving ground (ES: banco de pruebas) of CEMI's Financial Innovation Lab, alongside Intelligent Machines, the Open Sandbox and the Living Lab.

12Governance

Everything here is simulated. Every institution carries a Lab name, none of them is the entity it is modelled after, and none claims its endorsement. No real credentials, keys, BINs, routing identifiers, aliases or certificates exist anywhere in the ecosystem, and no real person, institution or money is involved.

This is NOT an «ambiente de prueba» under Art. 83 of the Reglamento de Sistemas de Pago. The ecosystem involves no real providers and no real external users, so it does not fall under the no-objection regime. A run is never a substitute for the Central Bank's no objection. Where your next step is an Art. 83 request, a run report is evidence for that request and nothing more.
Today this is a simulation, not a digital twin in the strict sense: there is not yet a finished system to be a twin of, since the instant-payments system is being built now. Our aim is to become the true digital twin of the Dominican financial ecosystem as it takes shape, following the work and guidelines of the Central Bank, the Superintendencia and the industry.

What a report is, and what it is not

A run report says what was tested: the scenario, the variant, the seed, the fidelity tier of every actor, the clock mode and the rule-catalogue version. A «pass» is a pass on that run, against that catalogue, at those fidelity tiers.

  • It is evidence you exercised a process end to end against the rules as the Lab has catalogued them, reproducible by anybody holding the seed.
  • It is not a certification, an authorization, a no objection, or a statement that any institution has reviewed anything. No institution being modelled here has endorsed this ecosystem.

The rule the whole catalogue is built around

A rule you cannot cite an article for is not a rule. It is either an assumption - and belongs in the numbered assumptions with a reason and a statement of what would settle it - or a Lab control, which goes into the catalogue with article: "Lab control" and a source saying plainly that it is not a regulatory statement. Borrowing a nearby article that does not say the thing is the one move that is never available.

No real personal data

The synthetic population is generated from the run seed and its generator is auditable. Nothing in it corresponds to a real person, and the identifier scheme is built so that nothing in it can be mistaken for one. Do not put real personal data in.

Where the values come from

Every regulatory figure in the catalogue is traceable to a published instrument: the Reglamento de Sistemas de Pago approved by the Segunda Resolución de la Junta Monetaria of 28 August 2025, and the Central Bank's instructivos IN-36-005, IN-36-023 and IN-36-024. Where a value had to be chosen because code cannot defer, it is recorded as a numbered Lab assumption and never dressed up as regulation. If you find a citation that does not say what we claim it says, tell us - the feedback form has a category for exactly that.

13Changelog

Newest first. A dated entry here is the notice a breaking change gets.

2026-09-05 - The console and the intake forms speak three languages

  • The console is trilingual. English, Spanish and French, switched in the masthead and kept across a reload. Every visible string comes from one dictionary (console/i18n.js); dates, figures and money are formatted with Intl for the active locale, so a French reader sees 20 000,00 RD$ where an English one sees RD$20,000.00. The language can be pinned with ?lang=en|es|fr, which is what a demo link should carry.
  • Both intake forms are published in French as well as English and Spanish, at /request-key/fr/ and /feedback/fr/, generated from the same vocabularies the gateway validates against.
  • A refused form now answers with codes, not prose. The errors array of a 422 carries stable identifiers - organization-required, email-required-to-answer, reference-required - and the page renders each one in the language its reader is already reading. If your integration matched on the English sentences, match on the codes instead.
  • Sign-in falls back to a redirect when the browser refuses the pop-up, which is what a locked-down corporate profile does.
  • This manual is still English and Spanish; the French edition is next, and the navigation says so.

2026-09-05 - Teams, la Población del Lab, the instructivos, and three corrections

  • Correction, Pagos al Instante. An order given outside the schedule becomes effective at 08:00 on the next BUSINESS day - «se hacen efectivos a las 8:00 a.m. del siguiente día laborable», from the Central Bank's own page. The Lab had been deferring to 07:00 on the next calendar day: the wrong hour and the wrong kind of day. A Friday-night order was executing on Saturday morning and now waits until Monday, which is the whole weekend. If your integration asserted the old behaviour, this will change your results.
  • Correction, the SGPI parameters. The ten-second final credit and the 24/7/365 availability are published on the Central Bank's SGPI page and are not articles of the Reglamento. The catalogue had been citing Arts. 60-61 beside both figures; those articles establish the SGPI and say who must participate in it, and carry neither number. Both rules now cite the page. A threshold with an article beside it that the article does not carry is exactly the fabricated regulatory fact this catalogue exists to prevent, and this was one.
  • New rule, Art. 22. An electronic-payment entity may hold the funds backing its managed balances only in its Central Bank current account, or in Central Bank or Ministerio de Hacienda securities pledged in favour of the Central Bank - never in a commercial bank. That is a different question from whether the float covers the balances, and a float can satisfy one and breach the other.
  • A finding now carries the instrument the article belongs to, because Art. 22 and IN-36-005 numeral 22 are both articles and only the instrument says which document a reader has to open.
  • One world per team. A team key now carries its team, and each team gets an isolated ecosystem: its own seed, clock, ledgers and alias directory. A team lists its own runs and nobody else's.
  • A team key opens the whole lane. Previously it opened only the machine lane on a signed-in instance, which meant a headless integration could not drive the control plane at all. The restriction existed because a key was a team and a team was isolated from nothing; a key now reaches exactly one world, so it is gone. This is the one behaviour change that could affect an existing integration, and it only widens what a key can do.
  • La Población del Lab. Every world is born with three banks, an EPE, the DD/DC administrator, four machines, 200 people, 40 businesses, accounts, cards, aliases and twelve flagged adversaries. GET /v1/directory hands you the whole of it.
  • New endpoints: GET /v1/directory, POST /v1/worlds/reset, GET /v1/worlds.
  • 26 rules adopted from the BCRD instructivos, taking the catalogue from 48 to 76 with the two corrections above: the RD$15,800,000 high-value threshold, the LBTR priority model and settlement prelation, the end-of-day queue flush, the electronic-payment-account funding-availability ceilings, the calendar-day cap window, the full-reserve float, the no-overdraft rule and the claim deadlines. Rules from the two 2021 instructivos carry needsRecheck.
  • This manual, in English and Spanish, generated from the sources.

2026-09-04 - Deployed

  • The Lab's own instance on the financial-ecosystem project: the gateway on Cloud Run, the console on Firebase Hosting, reports in Firestore.
  • Console sign-in with Firebase Auth, and an allow-list deciding who may start a run.
  • Reports behind a backend, so a report survives an instance restart.