Building Compliance-Native Financial APIs: A Developer's Pillar
How to design a financial API where compliance is enforced at the protocol layer, not bolted on: Travel Rule, Token-2022 hooks, ISO 20022 payloads, and webhook patterns.
PUBLISHED
April 5, 2026
AUTHOR
Bridge Research Team
READ_TIME
14 min read
CATEGORY
Pillar
The dominant pattern for building regulated financial APIs over the last decade has been simple: design the transaction layer first, then wrap it in a compliance layer that sits in front of the transfer endpoint. Know-your-customer checks happen before the call; Travel Rule messaging happens alongside the call; screening, monitoring and reporting happen after. The compliance layer is external to the transaction, and the API surface looks much like any other money movement API: create an authorisation, post a transfer, receive a confirmation.
This pattern works, up to a point. It breaks when the compliance requirement changes faster than the API can be redesigned, when the same transaction has to satisfy several regimes simultaneously, when regulators require evidence that a control cannot be bypassed, and when the business logic of the product depends on compliance state (for example, when a token cannot be transferred to an unverified wallet, or when a payment cannot be released until sanctions screening completes). In those cases the decoupled model produces either reduced safety (controls are optional or can race with the transfer) or reduced capability (compliance becomes a hand-brake that stops the API from being useful).
A compliance-native financial API inverts the pattern. The controls are part of the protocol. The transfer cannot be executed unless the compliance state is satisfied, because the transfer primitive itself checks and records the state. The API surface is not "transfer plus compliance"; it is a single call whose semantics include compliance. This pillar sets out what that means in practice, why it matters for engineering teams building regulated products, and what the architectural choices look like across identity, settlement, tokenisation and operations. We will reference Bridge's own implementation patterns where relevant, and link to deeper material on specific topics where appropriate.
Why APIs Alone Are Not Enough
The first argument for compliance-native design is evidence. A regulator reviewing an operator under the Pakistan Virtual Asset Regulation Act, the EU Markets in Crypto-Assets regulation, the Travel Rule under FATF Recommendation 16, or a central-bank RTGS scheme is not asking whether the operator intends to enforce a control. They are asking for evidence that the control cannot be bypassed. An API that enforces controls at the edge can usually be bypassed by a developer who has access to the underlying system: a hotfix, a privileged endpoint, a direct database write. An API whose primitive refuses to operate when the control fails cannot be bypassed in the same way, because the enforcement is on the settlement path itself.
The second argument is speed of change. Compliance rules change at a rate that would be punishing for a traditional API redesign cycle. A new sanctions list, a new Travel Rule threshold, a new reporting field, a new KYC requirement — each can arrive with a few weeks of lead time. Compliance-native APIs surface these changes as configuration rather than as breaking schema changes, because the primitive is expressed in terms of policy categories (for example, "this transfer must satisfy a Tier 2 KYC and a sanction check") rather than in terms of specific rules. The rules update inside the platform; the API contract remains stable.
The third argument is composability. In practice a regulated transaction touches several regimes at once — a cross-border stablecoin settlement might involve a Travel Rule message under FATF, an ISO 20022 reporting message under a central-bank scheme, a transfer hook on a tokenised asset under MiCA, and a GoAML report to a national FIU. A decoupled API requires the integrator to orchestrate all of these themselves, in the right order, with the right retries. A compliance-native API treats the composition as the job of the protocol, not of the caller. The caller states intent; the platform enforces the regimes that apply.
Teams building regulated products should read our guide to compliance-native fintech APIs at the product level alongside this article; this post focuses on the engineering architecture rather than the product surface.
Enforcement at the Protocol Layer
The core move is to put compliance checks inside the primitive that moves value, rather than before it. What that looks like in practice depends on the substrate.
On a permissioned ledger such as Corda, the primitive is a contract that governs what counts as a valid state transition. Bridge's settlement flows on Corda 5 — the current major version — use contract code that rejects any proposed state change unless the participating identities are verified against the identity service, the transaction carries a valid Travel Rule payload where required, and the posting on the ledger component is consistent. The transaction cannot be written to the notary's consumption set unless the contract passes. This is enforcement by the substrate; no application code sits between the call and the state change, so there is no path for a bypass.
On a permissionless ledger such as Solana, the primitive is a token program. Solana Token-2022 adds transfer hooks — custom programs that run as part of the transfer itself and can reject the transfer if their conditions are not met. A stablecoin on Token-2022 can require that both counterparties hold a non-expired attestation credential, that the transfer does not push either side through a sanctions threshold, and that the amount is within the holder's outbound limit for the day. The transfer instruction fails atomically if any condition fails. As with the Corda pattern, there is no state in which the transfer has happened but the controls have not.
Across chains, the common architectural element is the policy engine. Bridge separates policy from execution: the policy engine, implemented in the orchestration service, evaluates the compliance state for an intent (counterparties, asset, amount, jurisdictions) and returns a decision tree. The execution layer — Corda flows, EVM contracts, Solana programs — consumes the decision and executes only if the decision allows. In a multi-chain settlement the policy engine is called once; the individual chain primitives are called with the decision attached. This gives a consistent compliance semantic across chains without needing every chain to re-implement the same controls.
A practical test for whether an API is compliance-native is this: if a developer removes the compliance layer from the request path, does the API still work? If yes, the compliance is bolted on. If no — if the transfer will not execute without the compliance state — the compliance is native.
Token-2022 Transfer Hooks in Practice
Solana's Token-2022 standard is worth looking at closely because it shows how compliance-native enforcement can coexist with high throughput. Solana mainnet sustains in the order of two thousand transactions per second in typical conditions, and Token-2022 transfers are not a separate throughput class — they run on the same validators and in the same slots as ordinary SPL transfers. The compliance check therefore has to be cheap enough to run inline without degrading the chain.
The transfer hook extension allows a token mint to designate a program that must be called as part of every transfer. The hook program receives the transfer context — source, destination, amount, mint — and signs off or rejects. Typical hook conditions for regulated stablecoins include: membership in an allowlist of attested wallets; absence from a sanctions list; within the daily or per-transfer cap for the source; and satisfaction of any programme-specific rule (for example, "this token only moves between wallets that hold a MiCA-compliant attestation").
The architectural discipline in a transfer hook is to keep the hook deterministic and bounded. A hook that reaches out to an oracle on the compute path will be slow and will fail if the oracle is unreachable; a hook that reads from state that is not pre-loaded will miss the account in the transaction's account list. In practice hooks either read from an on-chain registry that the compliance service updates asynchronously, or they require the caller to include attestation accounts in the transaction.
The net effect is that an unverified wallet cannot hold the token at all, because a transfer to it fails; and a sanctioned wallet cannot move the token, because a transfer from it fails. The control is at the token layer, not at the API layer, and the token is what moves.
More detail on Bridge's Solana patterns is available in our Solana for regulated finance material.
ISO 20022 as a First-Class Payload
ISO 20022 is the messaging standard that has replaced SWIFT MT for the large majority of wholesale payment systems — Fedwire, CHAPS, TARGET2 and others completed the migration through 2025. For an API designer, the question is not whether to support ISO 20022 but how to treat it. In a compliance-native API, ISO 20022 is a first-class payload: the fields that carry originator, beneficiary, purpose, remittance information and regulatory reporting are part of the transfer object itself, not a sidecar report generated later.
This matters because the ISO 20022 fields are consumed by the downstream settlement system (for example, by the central bank's RTGS, by a correspondent's reconciliation, by a regulator's monitoring). If the fields are populated at transfer time, the whole downstream chain has them. If they are populated by a post-transfer reporting job, there is a window in which the settlement exists but the data does not, and that window is where reconciliation breaks and compliance evidence becomes ambiguous.
Concretely, a Bridge transfer intent carries a payload that maps cleanly to pacs.008 for interbank credit transfers and to pain.001 for customer-initiated payments, with the structured fields populated at construction. The fields are validated by the platform before the underlying settlement is executed; a transfer that fails ISO 20022 validation does not reach the ledger. This pattern is described further in our ISO 20022 and tokenised settlement analysis.
A corollary is that the API client is forced to think in structured terms from the start. Populating debtorAgent, creditorAgent, remittanceInformation and the purpose code is not an optional step before reporting; it is part of the transfer. Teams that try to add these fields later almost always find that the underlying transaction context has been lost, and the quality of the report suffers.
Idempotency, Retries and Observability
Compliance-native design does not remove the need for the usual financial-API hygiene. It makes it more important, because a bypass of idempotency can produce a control failure as well as a double payment.
Every transfer should carry a client-generated idempotency key that is unique per logical intent. The server persists the key with the transaction outcome; a retry with the same key returns the cached outcome rather than executing again. The key should be long-lived (hours to days) so that retries across process restarts still resolve correctly. In Bridge's design, the idempotency store is part of the orchestration service and spans all three integration surfaces — REST, webhooks, Kafka — so a client that submits the same intent by different paths gets the same outcome.
Retries should be asymmetric. A client that does not receive a confirmation should retry; a client that receives any definite outcome (success or failure) should not. The retries should be bounded and jittered to avoid thundering-herd behaviour against the platform. Exponential backoff with a cap of a few minutes is a reasonable default. A long-running transfer — for example, one that waits for a Corda notary to finalise — returns a pending status immediately and offers a completion signal via webhook, which the client can also poll via a status endpoint.
Observability is the third leg. A compliance-native transfer generates a chain of events: intent accepted, policy evaluated, attestation verified, Travel Rule sent, execution submitted, settlement finalised, reporting emitted. Each event carries the transfer's identity, the idempotency key, the identities of the parties, the jurisdictions engaged, and the decision outcomes. The events stream to Kafka and are available for both operational monitoring and regulatory evidence. A regulator asking "show me the chain of controls for this transfer" should be able to get a deterministic, complete answer in a single query.
The pattern is similar in shape to the webhook and event discipline described in our cross-border payment infrastructure pillar, and it carries over directly into multi-chain settlement.
Putting It Together: A Reference Call
To make the model concrete, consider a simple intent: transfer 10,000 USD-equivalent from a wallet in Pakistan to a wallet in the United Arab Emirates, with both counterparties holding Tier 2 verified identities. A compliance-native call looks like the following in pseudo-code (illustrative, not tied to a specific Bridge SDK method):
const intent = { idempotencyKey: "tx-2026-04-13-000124", from: { identity: "ident:pak:00123", chain: "corda", account: "cash-pkr-01" }, to: { identity: "ident:uae:00987", chain: "solana", mint: "usdc-token2022" }, amount: { value: "10000.00", currency: "USD" }, purpose: "remittance-personal", iso20022: { purposeCode: "CASH", remittanceInformation: "Family support - April" } }; const result = await bridge.settlement.execute(intent);
The platform runs the chain internally: identity verification (both ends), Travel Rule payload construction and exchange with the counterparty VASP, policy evaluation against Pakistan PVARA and UAE VASP rules, currency conversion via the quote router, Corda-side posting, bridge to Solana, and a Token-2022 transfer with the recipient attestation in the account list. Any failure at any stage aborts the intent cleanly and returns a structured error with a reason code. The client handles retries against the same idempotency key. The full event trail is available via Kafka, via the status endpoint, and via the webhook subscription the client has registered.
This is the shape of a compliance-native API: the caller states intent, the platform composes the regulated execution, and the outcome is either a completed and evidenced transfer or a structured rejection. For engineering teams, the practical next step is to look at the developer surface on /build and to treat the design ideas here as a starting point for your own platform's primitives. For identity-specific details see our identity material; for tokenisation, see tokenisation; and for Pakistan-specific controls, see our PVARA guide.
Trade-offs and When Not to Go Native
Compliance-native design is not free. The platform that enforces compliance at the protocol layer has to be operated to a higher reliability bar than a platform that merely wraps a simpler primitive, because a bug in the enforcement logic is a business-stopping event rather than a feature-flag rollback. The identity service has to be highly available, because a transfer that needs a verified identity cannot proceed while the identity service is down. The policy engine has to be deterministic and auditable, because an inconsistent decision from the engine invalidates the evidence it is supposed to generate. The chains of events have to be durable and complete, because a missing event is a missing piece of regulatory evidence.
These are engineering constraints rather than objections. They shape where compliance-native design is appropriate. For a platform that is building regulated financial infrastructure end-to-end — settlement, custody, tokenisation under a licence — the reliability bar has to be met regardless, and compliance-native primitives are the natural way to meet it. For a platform whose regulated surface is bounded (for example, a wallet that holds only small retail balances under a narrow licence), a simpler bolt-on design may still be defensible, provided the regulator accepts the evidence model.
The pragmatic path for most teams is a hybrid: the money movement primitives are compliance-native, and the surrounding product logic — reporting, analytics, customer experience — is built on top of the primitives using ordinary application patterns. The compliance-critical surface is small, well-tested and tightly supervised; the product surface is fast to evolve. This is the design that Bridge ships and the one we recommend to teams building similar products.
Read the developer docs on /build to go deeper, and contact the team if you are designing a compliance-native API and want to compare notes.