Reframe - A Universal Transformation Engine
Reframe is a high-performance, open-source rules engine for transforming any message format. Convert between SWIFT MT, ISO 20022, or custom formats using auditable JSONLogic rules.
Try the Interactive Playground →
Universal Transformation Engine
Reframe transforms any message format using auditable rules:
- SWIFT MT ↔ ISO 20022: Free CBPR+ package included
- Custom formats: Any format with JSONLogic transformation rules
# Quick start with Docker
docker pull plasmatic/reframe:latest
docker run -p 3000:3000 plasmatic/reframe:latest
Architecture
Reframe separates the transformation engine from business rules via packages. The engine handles parsing, rule evaluation, and validation - while packages contain the actual transformation logic.
Learn About the Architecture →
Why Choose Reframe?
Open Source Rules Engine
All transformation rules are externalized in auditable JSONLogic files. Inspect, modify, and extend any mapping logic. Apache 2.0 licensed.
High Performance
Built in Rust with sub-millisecond transformation latency. Process thousands of messages per second.
Standards Agnostic
Load the SWIFT CBPR+ package or create your own for proprietary formats.
Enterprise Ready
Hot-reload, GraphQL API, custom fields, and full audit trails. Deploy as a single Docker container.
Featured Package: SWIFT CBPR+ ISO 20022
Free, SR2025-compliant transformation package with 41+ scenarios:
| Category | Transformations |
|---|---|
| Customer Payments | MT103 ↔ pacs.008 |
| FI Transfers | MT202 ↔ pacs.009 |
| Statements | MT940 ↔ camt.053 |
View Complete Message Catalog →
Powered By Open Source
Reframe is built on a foundation of specialized open-source libraries:
| Library | Purpose | Links |
|---|---|---|
| Datalogic | JSONLogic rule evaluation | Docs · GitHub |
| Dataflow | Workflow orchestration | Docs · GitHub |
| Datafake | Test data generation | Docs · GitHub |
Each library has its own interactive playground for testing and learning.
Quick Comparison
| Feature | Reframe (Open Source) | Proprietary Solutions |
|---|---|---|
| License | Apache 2.0 (Free) | Expensive licensing |
| Rules | Auditable JSONLogic | Black-box logic |
| Standards | Universal (packages) | Limited scope |
| Performance | Sub-millisecond (Rust) | Slower (JVM) |
| Updates | Hot-reload rules | Vendor intervention |
Get Started
Resources
- GitHub: github.com/GoPlasmatic/Reframe
- CBPR+ Package: github.com/GoPlasmatic/reframe-package-swift-cbpr
- License: Apache License 2.0
Built by Plasmatic - Making message transformation transparent, fast, and reliable.
Interactive Playground
Test Reframe transformations, validation, and sample generation directly in your browser.
Full Playground
The complete playground with all features:
Features
Generate Tab
Create sample SWIFT MT or ISO 20022 messages for testing.
Validate Tab
Validate any message and see detailed error reports.
Transform Tab
Convert messages between MT and ISO 20022 formats.
Configuration
API URL
By default, the playground connects to https://reframeapi.goplasmatic.io. To use a local instance:
- Click the Settings icon in the playground
- Enter your local API URL (e.g.,
http://localhost:3000) - Click Save
Your preference is stored in browser local storage.
Running Locally
Start Reframe locally:
docker run -p 3000:3000 plasmatic/reframe:latest
Then configure the playground to use http://localhost:3000.
Individual Widgets
For focused testing, use the individual playground pages:
- Generator - Generate sample messages
- Validator - Validate messages
- Transformer - Transform between formats
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Ctrl/Cmd + Enter | Execute current operation |
Ctrl/Cmd + L | Clear output |
Ctrl/Cmd + K | Copy output to clipboard |
Tips
Testing Transformations
- Generate a sample message
- Copy the output
- Switch to Transform tab
- Paste and transform
- Validate the result
Debugging Issues
Enable Debug Mode in the transformer to see:
- Each workflow that executed
- Intermediate values
- Field mapping results
API Integration
Each operation shows the API Request & Response panel. Use this to:
- Copy curl commands for your scripts
- See exact request format
- Debug API integration issues
The Open Source Advantage
Why financial institutions are choosing open source for ISO 20022 transformation.
The Challenge with Proprietary Solutions
Traditional SWIFT MT to ISO 20022 transformation solutions share common limitations:
- Black-box logic: Transformation rules hidden in compiled code
- Vendor lock-in: Difficult to switch providers or customize behavior
- Expensive licensing: Per-message fees or costly annual licenses
- Slow updates: Waiting for vendors to support new standards
- Limited auditability: Cannot verify transformation correctness
How Reframe is Different
100% Transparent Rules
Every transformation rule in Reframe is defined in human-readable JSON:
{
"path": "data.output.CdtTrfTxInf.PmtId.InstrId",
"logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
}
You can inspect, audit, and modify any rule. No hidden logic, no surprises.
Full Auditability
For regulated financial institutions, auditability is essential:
- Complete rule visibility: Review every field mapping and business rule
- Version control: Track changes to transformation rules in Git
- Compliance documentation: Generate rule documentation for auditors
- Testing transparency: Understand exactly why a transformation produces its output
Cost Efficiency
| Cost Factor | Proprietary | Reframe |
|---|---|---|
| License fees | $50K-500K/year | Free (Apache 2.0) |
| Per-message fees | $0.01-0.10/message | None |
| Customization | Vendor rates ($200-400/hr) | In-house or community |
| Support | Mandatory contracts | Optional, community available |
Control Over Your Infrastructure
With Reframe, you own your transformation infrastructure:
- Self-hosted: Run on your infrastructure, your cloud, your rules
- No external dependencies: No calls to vendor APIs during transformation
- Data sovereignty: Messages never leave your environment
- Customization: Modify rules to match your specific business requirements
Community and Ecosystem
Reframe is part of a growing ecosystem:
- Active development: Regular updates and improvements
- Community support: GitHub issues, discussions, and contributions
- Ecosystem libraries: Datalogic, Dataflow, Datafake all open source
- Enterprise support: Available for organizations that need it
Migration Path
Moving from proprietary solutions to Reframe:
- Evaluate: Run Reframe alongside your current solution
- Compare: Verify transformation outputs match expectations
- Customize: Adjust rules for your specific requirements
- Migrate: Gradually shift traffic to Reframe
- Optimize: Fine-tune performance and add custom features
Real-World Benefits
For Development Teams
- Debug transformation issues by reading the rules
- Extend functionality without vendor involvement
- Test edge cases with full visibility into logic
For Compliance Teams
- Document transformation logic for regulators
- Verify SR2025 compliance in detail
- Audit trail of all rule changes
For Operations Teams
- Hot-reload configuration without downtime
- Monitor transformation performance
- Scale horizontally as needed
Learn About the Architecture →
Architecture Overview
How Reframe achieves high-performance, transparent message transformation.
Universal, Package-Based Design
Reframe is a universal message transformation engine - not tied to any specific standard. The engine loads transformation packages that define the rules for converting between formats.
Key insight: Reframe is completely format-agnostic - all SWIFT, ISO 20022, and CBPR+ knowledge lives in loadable packages.
Design Principles
Reframe is built on four core principles:
- Separation of concerns: Engine logic completely separate from transformation rules
- Transparency: All business rules in external, auditable JSON files
- Performance: Rust implementation with zero-copy processing
- Universality: Package-based architecture supports any message standard
System Architecture
┌──────────────────────────────────────────────┐
│ Reframe Engine │
│ │
Input Message │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ Output Message
(MT or MX) ────▶│ │ Parser │─▶│Workflow │─▶│Publisher│─────▶ │ (MX or MT)
│ └─────────┘ │ Engine │ └─────────┘ │
│ └────┬────┘ │
│ │ │
└────────────────────┼─────────────────────────┘
│ loads
┌────────────────────▼─────────────────────────┐
│ Transformation Package │
│ │
│ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Workflows │ │ Field Mappings │ │
│ │ (JSON) │ │ (JSONLogic) │ │
│ └─────────────┘ └─────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Conditions │ │ Validation Rules │ │
│ │ (JSONLogic) │ │ (JSONLogic) │ │
│ └─────────────┘ └─────────────────────┘ │
└──────────────────────────────────────────────┘
Core Components
1. Reframe Engine
The engine handles all runtime processing:
| Component | Responsibility |
|---|---|
| Parser | Detects message format (MT/MX), parses into internal representation |
| Workflow Engine | Orchestrates transformation pipeline using Dataflow |
| Rule Evaluator | Executes JSONLogic expressions using Datalogic |
| Publisher | Generates output in target format (MT or MX XML) |
| Validator | Validates messages against schemas and business rules |
2. Transformation Package
Packages contain all transformation logic in JSON. Reframe can load any package - it’s not limited to a specific format.
Available Packages:
| Package | Description | Link |
|---|---|---|
| SWIFT CBPR+ MT ↔ ISO 20022 | SR2025 compliant bidirectional transformations (free) | GitHub |
| Custom packages | Create your own for FIX, proprietary formats, etc. | Package Guide |
Example Package Structure (SWIFT CBPR+):
reframe-package-swift-cbpr/
├── reframe-package.json # Package metadata
├── transform/
│ ├── index.json # Workflow registry
│ ├── outgoing/ # MT → MX rules
│ │ ├── MT103/
│ │ │ ├── document-mapping.json
│ │ │ ├── bah-mapping.json
│ │ │ └── precondition.json
│ │ └── MT202/
│ └── incoming/ # MX → MT rules
│ ├── pacs008/
│ └── pacs009/
├── validate/ # Validation rules
└── generate/ # Sample generation
3. Technology Stack
| Layer | Technology | Purpose |
|---|---|---|
| Runtime | Rust + Tokio | Async, high-performance execution |
| Workflow | Dataflow | Pipeline orchestration |
| Rules | Datalogic | JSONLogic evaluation |
| MT Parser | swift-mt-message | SWIFT MT parsing |
| MX Parser | mx-message | ISO 20022 XML parsing |
| API | Axum | HTTP/REST server |
Transformation Pipeline
MT to ISO 20022 (Outgoing)
MT103 Input
│
▼
┌─────────────────┐
│ 1. Parse MT │ Extract blocks and fields
└────────┬────────┘
│
▼
┌─────────────────┐
│ 2. Detect Type │ Identify MT variant (standard/STP/reject/return)
└────────┬────────┘
│
▼
┌─────────────────┐
│ 3. Map BAH │ Create Business Application Header
└────────┬────────┘
│
▼
┌─────────────────┐
│ 4. Pre-validate │ Check business rule preconditions
└────────┬────────┘
│
▼
┌─────────────────┐
│ 5. Map Document │ Transform fields to ISO 20022 paths
└────────┬────────┘
│
▼
┌─────────────────┐
│ 6. Post-validate│ Verify output compliance
└────────┬────────┘
│
▼
┌─────────────────┐
│ 7. Publish XML │ Generate ISO 20022 XML envelope
└────────┬────────┘
│
▼
pacs.008 Output
ISO 20022 to MT (Incoming)
The reverse flow follows a similar pattern, extracting data from XML and constructing MT blocks.
Performance Characteristics
Zero-Copy Processing
- Pre-compiled JSONLogic rules at startup
- No runtime parsing of rule definitions
- Direct memory access for string operations
Async Architecture
- Tokio runtime with configurable worker threads
- Non-blocking I/O for all operations
- Handles thousands of concurrent requests
Benchmarks
| Operation | Latency | Throughput |
|---|---|---|
| MT103 → pacs.008 | <1ms | 5,000+ msg/sec |
| pacs.008 → MT103 | <1ms | 5,000+ msg/sec |
| Validation | <0.5ms | 10,000+ msg/sec |
Benchmarks on standard cloud VM (4 vCPU, 8GB RAM)
Scalability
Horizontal Scaling
- Stateless design enables simple replication
- No shared state between instances
- Load balance across multiple containers
Deployment Options
┌─────────────┐
│ Load │
│ Balancer │
└──────┬──────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Reframe │ │ Reframe │ │ Reframe │
│ #1 │ │ #2 │ │ #3 │
└─────────┘ └─────────┘ └─────────┘
Hot Reload
Update transformation rules without restarting the engine. See Hot Reload Guide →
Get Started with Quick Start →
Use Cases
Real-world applications of Reframe for message transformation.
Reframe’s package-based architecture supports any message format. Below are common use cases, including the free SWIFT CBPR+ package for ISO 20022 transformations.
Bank Modernization
MT to ISO 20022 Migration
Financial institutions worldwide are migrating from SWIFT MT to ISO 20022. Reframe enables:
Challenge: Banks need to convert existing MT-based systems to support ISO 20022 while maintaining backward compatibility.
Solution with Reframe:
- Run Reframe alongside existing systems during transition
- Convert outgoing MT messages to ISO 20022 for SWIFT
- Convert incoming ISO 20022 to MT for legacy systems
- Gradually migrate internal systems while maintaining interoperability
Legacy Core Banking Reframe SWIFT Network
(MT) (ISO 20022)
│ │
│ MT103 │
├─────────────────▶ Transform ─────────────────▶│
│ to MX pacs.008
│ │
│ MT103 │
◀─────────────────◀ Transform ◀─────────────────┤
│ to MT pacs.008
Phased Migration Benefits
- No big bang: Migrate message types incrementally
- Fallback ready: Keep MT capability while building MX
- Testing: Compare outputs side-by-side
- Timeline control: Move at your own pace
Payment Hub Integration
Central Transformation Service
Large organizations with multiple payment channels benefit from centralized transformation:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Channel 1 │ │ Channel 2 │ │ Channel 3 │
│ (Legacy) │ │ (Modern) │ │ (Partner) │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
│ MT103 │ pacs.008 │ Mixed
│ │ │
└──────────────────┼──────────────────┘
│
┌─────▼─────┐
│ Reframe │
│ Hub │
└─────┬─────┘
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
To SWIFT To Partner To Archive
(pacs.008) (MT103) (Both)
Benefits:
- Single transformation engine for all channels
- Consistent mapping across the organization
- Centralized rule management and updates
- Unified logging and monitoring
Testing and Certification
Test Message Generation
Reframe generates valid test messages for any supported type:
curl -X POST http://localhost:3000/api/generate \
-H "Content-Type: application/json" \
-d '{"message_type": "MT103", "scenario": "standard"}'
Use cases:
- Integration testing: Generate realistic messages for system testing
- Certification: Create messages for SWIFT certification programs
- Development: Provide developers with valid sample messages
- Training: Generate examples for training materials
Transformation Testing
Verify transformations before production:
# Transform and validate
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "<MT103 content>",
"validation": true,
"debug": true
}'
The debug mode shows:
- Each rule that was applied
- Intermediate values during transformation
- Validation results at each step
Regulatory Compliance
SR2025 Compliance
SWIFT’s Standards Release 2025 mandates ISO 20022 for cross-border payments. Reframe provides:
- Full SR2025 support: All required message types and fields
- CBPR+ compliance: Cross-Border Payments and Reporting guidelines
- Audit trail: Complete logging of all transformations
- Rule documentation: Export rules for compliance review
Compliance Documentation
Generate compliance documentation from rules:
// Example rule with documentation
{
"path": "data.output.CdtTrfTxInf.ChrgBr",
"logic": {
"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
"SHAR",
{"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
"DEBT",
"CRED"
]}
]
},
"documentation": {
"source": "MT Tag 71A Details of Charges",
"target": "ChargeBearerType1Code",
"rule": "SHA→SHAR, OUR→DEBT, BEN→CRED",
"reference": "CBPR+ Usage Guidelines 4.2.1"
}
}
Message Validation
Pre-transformation Validation
Validate messages before processing:
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message": "<message content>",
"business_validation": true
}'
Validation checks:
- Format compliance (MT structure, XML schema)
- Field content rules (BIC format, amount precision)
- Business rules (valid currency pairs, date ranges)
- Network validation rules (SWIFT-specific)
Validation Use Cases
- Gateway validation: Reject invalid messages before processing
- Quality assurance: Ensure message quality across channels
- Debugging: Identify specific validation failures
- Monitoring: Track validation failure patterns
Multi-Market Support
Regional Customization
Different markets may require rule variations:
┌─────────────────────────────────────────────────┐
│ Reframe Engine │
└─────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ CBPR+ │ │ SEPA │ │ Target2 │
│ Package │ │ Package │ │ Package │
└─────────┘ └─────────┘ └─────────┘
Benefits:
- Share common rules across markets
- Customize specific mappings per region
- Hot-swap packages for different contexts
- Maintain market-specific compliance
Development and DevOps
Integrate Reframe into your development pipeline with Docker and standard CI/CD tools. Use the GitHub Container Registry image in your workflows:
# GitHub Actions example
services:
reframe:
image: plasmatic/reframe:latest
ports:
- 3000:3000
For full deployment configurations, see Kubernetes Deployment →
Beyond SWIFT: Custom Packages
Reframe is not limited to SWIFT messaging. Create packages for any transformation need:
FIX Protocol Transformation
Convert between FIX and other formats:
FIX 4.4 Message Reframe Internal Format
│ │
│ NewOrderSingle │
├─────────────────▶ Transform ─────────────────▶│
│ JSON/XML
Proprietary Format Migration
Organizations with legacy proprietary formats can:
- Create packages to transform to industry standards
- Maintain both old and new formats during migration
- Validate against custom business rules
Multi-Format Hub
A single Reframe instance can load multiple packages:
┌─────────────────────────────────────────────────────┐
│ Reframe Engine │
├─────────────────────────────────────────────────────┤
│ Loaded Packages │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ CBPR+ │ │ FIX │ │ Custom Format A │ │
│ │ MT↔MX │ │ 4.4↔5.0 │ │ Legacy→XML │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────┘
Building Custom Packages
See the Packages and Rules guide for creating your own transformation packages.
Transformation Engine
Reframe’s open source rules engine transforms messages between any formats using auditable JSONLogic rules. Load transformation packages for SWIFT MT↔ISO 20022 or custom formats.
How It Works
The transformation engine follows a simple pipeline:
Input Message → Parse → Detect Format → Transform → Validate → Output
- Parse: Extract structured data from input format
- Detect: Identify message type and target transformation
- Transform: Apply JSONLogic mapping rules
- Validate: Check output against format rules
- Output: Generate target format message
Format Detection
The engine automatically detects input formats based on package rules:
| Package | Detection | Example |
|---|---|---|
| CBPR+ | {1: prefix = MT, XML namespace = ISO 20022 | SWIFT messages |
| Custom | Package-defined patterns | Any format |
Transformation Pipeline
Every transformation follows this generic pipeline:
┌────────────────────────────────────────────────────────────┐
│ Generic Transformation Pipeline │
├────────────────────────────────────────────────────────────┤
│ 1. Parse Input → Extract structured data │
│ 2. Detect Target → Identify output format │
│ 3. Pre-conditions → Validate business rules │
│ 4. Map Fields → Apply JSONLogic transformations │
│ 5. Post-conditions → Validate output │
│ 6. Publish → Generate target format │
└────────────────────────────────────────────────────────────┘
Packages customize each stage with format-specific rules.
CBPR+ Package Example
For SWIFT CBPR+ transformations:
- MT → ISO 20022: Parse MT blocks → Map to pacs/camt XML → Validate CBPR+ rules
- ISO 20022 → MT: Parse XML → Map to MT fields → Validate MT structure
Field Mapping
The core of transformation is field mapping using JSONLogic rules.
Simple Mapping
Direct field copy:
{
"path": "data.output.field_name",
"logic": {"var": "data.input.source_field"}
}
Conditional Mapping
Logic-based transformation:
{
"path": "data.output.status",
"logic": {
"if": [
{"==": [{"var": "data.input.code"}, "A"]}, "ACCEPTED",
{"==": [{"var": "data.input.code"}, "R"]}, "REJECTED",
"UNKNOWN"
]
}
}
Composite Mapping
Combining multiple fields:
{
"path": "data.output.amount",
"logic": {
"object": {
"currency": {"var": "data.input.ccy"},
"value": {"var": "data.input.amt"}
}
}
}
See JSONLogic Rules for complete syntax reference.
Validation Integration
Transformation can include validation:
curl -X POST http://localhost:3000/api/transform \
-d '{"message": "...", "validation": true}'
When enabled:
- Input message validated before transformation
- Output message validated after transformation
- Validation errors included in response
Error Handling
Transformation errors are categorized:
| Error Type | Description |
|---|---|
| Parse Error | Cannot parse input message format |
| Mapping Error | Field transformation failed |
| Validation Error | Output fails format rules |
| Rule Error | Business rule violation |
Error responses include error code, pipeline location, and source field.
Learn About Packages → · JSONLogic Rules →
Packages and Rules
How Reframe organizes transformation logic into modular, reusable packages.
Key Concept: Engine vs Package
Reframe is a universal transformation engine. It doesn’t know anything about SWIFT, ISO 20022, or any specific message format. All transformation knowledge lives in packages.
| Component | Contains | Examples |
|---|---|---|
| Reframe Engine | Workflow execution, rule evaluation, message parsing framework | Core engine code |
| Packages | Message-specific transformation rules, schemas, validation | SWIFT CBPR+, FIX, custom formats |
This means you can use Reframe for any message transformation - not just SWIFT/ISO 20022.
Benefits
This separation of engine and packages enables:
- Customization: Modify rules without changing engine code
- Multiple packages: Load different rule sets for different contexts
- Version control: Track rule changes independently
- Hot reload: Update rules without restarting
For architecture diagrams, see Architecture Overview →
Package Structure
A Reframe package follows this structure:
reframe-package-swift-cbpr/
├── reframe-package.json # Package metadata
│
├── transform/ # Transformation workflows
│ ├── index.json # Workflow registry
│ ├── 00-detect-format.json # Format detection
│ │
│ ├── outgoing/ # MT → MX rules
│ │ ├── parse-mt.json # Common MT parser
│ │ ├── combine-xml.json # XML assembly
│ │ ├── MT103/ # MT103-specific rules
│ │ │ ├── bah-mapping.json
│ │ │ ├── document-mapping.json
│ │ │ ├── precondition.json
│ │ │ └── postcondition.json
│ │ └── MT202/
│ │ └── ...
│ │
│ └── incoming/ # MX → MT rules
│ ├── parse-mx.json # Common MX parser
│ ├── pacs008/ # pacs.008-specific rules
│ │ ├── 01-variant-detection.json
│ │ ├── 02-preconditions.json
│ │ ├── 03-headers-mapping.json
│ │ └── ...
│ └── pacs009/
│ └── ...
│
├── validate/ # Validation workflows
│ ├── index.json
│ ├── validate-mt.json
│ └── validate-mx.json
│
├── generate/ # Sample generation
│ ├── index.json
│ ├── generate-mt.json
│ └── generate-mx.json
│
└── scenarios/ # Test scenarios
├── index.json
├── outgoing/
│ └── mt103_to_pacs008_standard.json
└── incoming/
└── pacs008_to_mt103.json
Package Metadata
The reframe-package.json file defines package identity:
{
"id": "swift-cbpr-mt-mx",
"name": "SWIFT CBPR+ MT <-> MX Transformations",
"version": "2.1.2",
"description": "SR2025 compliant CBPR+ transformations",
"engine_version": "3.1.4",
"author": "Plasmatic",
"license": "Apache-2.0",
"workflows": {
"transform": {
"path": "transform",
"entry_point": "index.json"
},
"generate": {
"path": "generate",
"entry_point": "index.json"
},
"validate": {
"path": "validate",
"entry_point": "index.json"
}
},
"scenarios": {
"path": "scenarios",
"entry_point": "index.json"
}
}
Workflow Definition
Workflows are defined in JSON with this structure:
{
"id": "mt103-document-mapping",
"name": "MT103 Document Mapping",
"description": "Maps MT103 fields to pacs.008 document",
"priority": 5,
"condition": {
"and": [
{"==": [{"var": "metadata.direction"}, "outgoing"]},
{"==": [{"var": "metadata.message_type"}, "MT103"]}
]
},
"tasks": [
{
"id": "map-payment-id",
"name": "Map Payment Identification",
"function": {
"name": "map",
"input": {
"mappings": [
{
"path": "data.output.PmtId.InstrId",
"logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
},
{
"path": "data.output.PmtId.EndToEndId",
"logic": {"var": "data.SwiftMT.fields.21.related_reference"}
}
]
}
}
}
]
}
Workflow Properties
| Property | Description |
|---|---|
id | Unique identifier |
priority | Execution order (lower = earlier) |
condition | JSONLogic expression determining when workflow runs |
tasks | Array of tasks to execute |
Task Properties
| Property | Description |
|---|---|
id | Task identifier |
function.name | Function to execute (map, validation, custom) |
function.input | Function-specific configuration |
condition | Optional condition for task execution |
Rule Organization
Rules are organized by message type and transformation stage:
Outgoing (MT → MX)
transform/outgoing/MT103/
├── bah-mapping.json # Priority 3: Business Application Header
├── precondition.json # Priority 4: Pre-transformation validation
├── document-mapping.json # Priority 5: Field transformation
└── postcondition.json # Priority 6: Post-transformation validation
Incoming (MX → MT)
transform/incoming/pacs008/
├── 01-variant-detection.json # Detect target MT type
├── 02-preconditions.json # Validate transformation
├── 03-headers-mapping.json # Map MT headers
├── 04-mandatory-fields.json # Required fields
├── 05-amount-fields.json # Amount handling
├── 06-party-fields.json # Party information
├── 07-agent-fields.json # Agent (bank) information
├── 08-remittance-fields.json # Remittance details
└── 09-postconditions.json # Final validation
Priority-Based Execution
Workflows execute in priority order:
Priority 1: parse-mt.json ─── Parse input
Priority 2: method-detection.json ─── Detect variant
Priority 3: bah-mapping.json ─── Map header
Priority 4: precondition.json ─── Validate
Priority 5: document-mapping.json ─── Transform
Priority 6: postcondition.json ─── Validate output
Priority 10: combine-xml.json ─── Generate XML
This ensures:
- Parsing happens before mapping
- Validation occurs at appropriate stages
- Output generation happens last
Loading Packages
Default Package Path
# Environment variable
export REFRAME_PACKAGE_PATH=/path/to/packages
# Or in reframe.config.json
{
"packages": [
{
"path": "/packages/swift-cbpr",
"enabled": true
}
]
}
Docker Volume Mount
services:
reframe:
image: plasmatic/reframe:latest
volumes:
- ./my-package:/packages/my-package
environment:
- REFRAME_PACKAGE_PATH=/packages
Packages can be hot-reloaded. See Hot Reload →
Creating Custom Packages
1. Create Package Structure
mkdir -p my-package/{transform,validate,generate,scenarios}
2. Define Package Metadata
// my-package/reframe-package.json
{
"id": "my-custom-package",
"name": "My Custom Transformations",
"version": "1.0.0",
"engine_version": "3.1.0",
"workflows": {
"transform": {"path": "transform", "entry_point": "index.json"}
}
}
3. Create Workflow Index
// my-package/transform/index.json
{
"workflows": [
{"path": "my-transformation.json"}
]
}
4. Define Transformation Rules
// my-package/transform/my-transformation.json
{
"id": "my-transform",
"name": "My Custom Transformation",
"priority": 5,
"condition": {"==": [{"var": "metadata.type"}, "custom"]},
"tasks": [
// ... your mapping tasks
]
}
Related Pages
- JSONLogic Rules - Business rule syntax and examples
- Transformation Engine - Core engine architecture
- Workflow Orchestration - Multi-step transformation flows
- CBPR+ Package Guide - SWIFT CBPR+ package details
- Hot Reload - Update rules without restart
JSONLogic Rules
How Reframe uses JSONLogic for business rules and field transformations.
What is JSONLogic?
JSONLogic is a standard for expressing business logic as JSON. It provides:
- Portable rules: Same rules work across languages and platforms
- Human-readable: Logic expressed in familiar JSON structure
- Safe evaluation: No arbitrary code execution
- Testable: Rules can be validated independently
Reframe uses Datalogic, a high-performance Rust implementation of JSONLogic with 59 built-in operators.
Basic Syntax
JSONLogic expressions follow this pattern:
{ "operator": [arguments] }
Variable Access
Read data from the message context:
{"var": "data.SwiftMT.fields.20.transaction_reference"}
This accesses:
data
└── SwiftMT
└── fields
└── 20
└── transaction_reference → "REF123456"
Comparison
{"==": [{"var": "data.field"}, "expected_value"]}
{"!=": [{"var": "data.field"}, "unexpected_value"]}
{">": [{"var": "data.amount"}, 10000]}
{">=": [{"var": "data.amount"}, 0]}
Boolean Logic
{"and": [condition1, condition2]}
{"or": [condition1, condition2]}
{"!": [condition]}
{"!!": [value]} // Convert to boolean
Common Transformation Patterns
Direct Mapping
Copy a value from source to target:
{
"path": "data.output.InstrId",
"logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
}
Conditional Mapping
Map different values based on conditions:
{
"path": "data.output.ChrgBr",
"logic": {
"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
"SHAR",
{"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
"DEBT",
"CRED"
]}
]
}
}
Default Values
Provide fallback when source is missing:
{
"path": "data.output.PmtTpInf.SvcLvl.Cd",
"logic": {
"or": [
{"var": "data.SwiftMT.fields.23B.bank_operation_code"},
"G001"
]
}
}
String Concatenation
Combine multiple fields:
{
"path": "data.output.FullName",
"logic": {
"cat": [
{"var": "data.first_name"},
" ",
{"var": "data.last_name"}
]
}
}
String Extraction
Extract portions of a string:
{
"path": "data.output.CountryCode",
"logic": {
"substr": [
{"var": "data.SwiftMT.fields.50K.account"},
0,
2
]
}
}
Array Operations
Map (Transform Each Element)
{
"map": [
{"var": "data.items"},
{"cat": ["Item: ", {"var": ""}]}
]
}
Filter
{
"filter": [
{"var": "data.transactions"},
{">": [{"var": "amount"}, 1000]}
]
}
Reduce (Aggregate)
{
"reduce": [
{"var": "data.amounts"},
{"+": [{"var": "accumulator"}, {"var": "current"}]},
0
]
}
Check All/Some/None
{"all": [{"var": "data.items"}, {"!!": {"var": "valid"}}]}
{"some": [{"var": "data.items"}, {"==": [{"var": "status"}, "active"]}]}
{"none": [{"var": "data.items"}, {"<": [{"var": "amount"}, 0]}]}
Object Construction
Create Objects
Build complex structures:
{
"path": "data.output.Amt",
"logic": {
"object": {
"Ccy": {"var": "data.SwiftMT.fields.32A.currency"},
"value": {"var": "data.SwiftMT.fields.32A.amount"}
}
}
}
Nested Objects
{
"path": "data.output.Dbtr",
"logic": {
"object": {
"Nm": {"var": "data.SwiftMT.fields.50K.name"},
"PstlAdr": {
"object": {
"Ctry": {"var": "data.country"},
"AdrLine": {"var": "data.address_lines"}
}
}
}
}
}
Date and Time Operations
Current Timestamp
{"now": []}
Format Date
{
"format_date": [
{"var": "data.date"},
"%Y-%m-%d"
]
}
Parse Date
{
"parse_date": [
{"var": "data.date_string"},
"%y%m%d"
]
}
Validation Rules
Use JSONLogic for validation:
{
"id": "validate-amount",
"function": {
"name": "validation",
"input": {
"rules": [
{
"logic": {">": [{"var": "data.amount"}, 0]},
"message": "Amount must be positive"
},
{
"logic": {"!!": {"var": "data.currency"}},
"message": "Currency is required"
},
{
"logic": {
"in": [
{"var": "data.currency"},
["USD", "EUR", "GBP", "JPY"]
]
},
"message": "Invalid currency code"
}
]
}
}
}
CBPR+ Rule Examples
Charge Bearer Mapping
// MT Tag 71A to ISO 20022 ChargeBearerType1Code
{
"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
"SHAR",
{"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
"DEBT",
{"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "BEN"]},
"CRED",
"SHAR"
]}
]}
]
}
Service Level Determination
// Determine CBPR+ service level from MT fields
{
"if": [
{"==": [{"var": "data.SwiftMT.fields.23E.instruction_code"}, "URGP"]},
"G001",
{"if": [
{"==": [{"var": "data.SwiftMT.fields.23B.bank_operation_code"}, "SPAY"]},
"G003",
"G002"
]}
]
}
Party Identification
// Build creditor identification from MT fields
{
"object": {
"Nm": {"var": "data.SwiftMT.fields.59.beneficiary_name"},
"PstlAdr": {
"object": {
"AdrLine": {
"filter": [
{"var": "data.SwiftMT.fields.59.address_lines"},
{"!!": {"var": ""}}
]
}
}
},
"Id": {
"if": [
{"!!": {"var": "data.SwiftMT.fields.59.account"}},
{
"object": {
"OrgId": {
"object": {
"Othr": {
"object": {
"Id": {"var": "data.SwiftMT.fields.59.account"}
}
}
}
}
}
},
null
]
}
}
}
Testing Rules
Test rules in the Datalogic playground:
Example test:
// Rule
{
"if": [
{">": [{"var": "amount"}, 10000]},
"HIGH",
"NORMAL"
]
}
// Data
{"amount": 50000}
// Result
"HIGH"
Operator Reference
Comparison Operators
==, ===, !=, !==, >, >=, <, <=
Boolean Operators
and, or, !, !!
Numeric Operators
+, -, *, /, %, min, max, abs
String Operators
cat, substr, in, starts_with, ends_with, upper, lower, trim
Array Operators
map, filter, reduce, all, some, none, merge, sort
Control Flow
if, ?:, ??
Date/Time
now, datetime, format_date, parse_date, date_diff
Related Pages
- Packages and Rules - How Reframe organizes transformation logic
- Workflow Orchestration - Multi-step transformation flows
- Transformation Engine - Core engine architecture
- Interactive Playground - Try transformations online
- CBPR+ Package Guide - SWIFT MT to ISO 20022 rules
Workflow Orchestration
How Reframe orchestrates transformation pipelines using Dataflow.
Dataflow Engine
Reframe uses Dataflow for workflow orchestration. Dataflow provides:
- Pre-compiled workflows: All rules compiled at startup, zero runtime parsing
- Priority-based execution: Workflows execute in defined order
- Conditional routing: Rules determine which workflows apply
- Audit trail: Complete record of all transformations
Workflow Execution Model
Input Message
│
▼
┌───────────────────────┐
│ Message Context │
│ • data │
│ • metadata │
│ • temp_data │
└───────────┬───────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│Workflow │ │Workflow │ │Workflow │
│ P:1 │────▶│ P:5 │────▶│ P:10 │
└─────────┘ └─────────┘ └─────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────┐
│ Updated Context │
└─────────────────────────────────────────┘
│
▼
Output Message
Message Context
Every message flows through with a context object:
{
"context": {
"data": {
"SwiftMT": { /* parsed MT message */ },
"output": { /* transformation output */ }
},
"metadata": {
"direction": "outgoing",
"message_type": "MT103",
"variant": "standard"
},
"temp_data": {
/* intermediate calculations */
}
},
"audit_trail": [
/* record of all changes */
],
"errors": [
/* any errors encountered */
]
}
Context Sections
| Section | Purpose |
|---|---|
data | Primary business data (input and output) |
metadata | Routing and tracking information |
temp_data | Intermediate processing results |
audit_trail | Record of all modifications |
errors | Collected errors and warnings |
Workflow Structure
A workflow definition:
{
"id": "mt103-transform",
"name": "MT103 Transformation",
"description": "Transform MT103 to pacs.008",
"priority": 5,
"condition": {
"and": [
{"==": [{"var": "metadata.direction"}, "outgoing"]},
{"==": [{"var": "metadata.message_type"}, "MT103"]}
]
},
"error_handling": "continue",
"tasks": [
{
"id": "map-payment-info",
"name": "Map Payment Information",
"function": {
"name": "map",
"input": {
"mappings": [/* field mappings */]
}
}
}
]
}
Workflow Properties
| Property | Type | Description |
|---|---|---|
id | string | Unique workflow identifier |
name | string | Human-readable name |
priority | number | Execution order (lower = earlier) |
condition | JSONLogic | When this workflow should run |
error_handling | string | "continue" or "stop" on error |
tasks | array | Tasks to execute |
Priority-Based Execution
Workflows execute in priority order:
Priority 1: parse-mt.json
│
▼ (condition check)
Priority 2: detect-variant.json
│
▼ (condition check)
Priority 3: bah-mapping.json
│
▼ (condition check)
Priority 4: precondition.json
│
▼ (condition check)
Priority 5: document-mapping.json
│
▼ (condition check)
Priority 6: postcondition.json
│
▼ (condition check)
Priority 10: publish-xml.json
Each workflow’s condition is evaluated:
- Condition true: Workflow executes
- Condition false: Workflow skipped
Task Types
Map Task
Transform data using JSONLogic:
{
"id": "map-fields",
"function": {
"name": "map",
"input": {
"mappings": [
{
"path": "data.output.field1",
"logic": {"var": "data.input.source_field"}
},
{
"path": "data.output.field2",
"logic": {"cat": [{"var": "data.a"}, {"var": "data.b"}]}
}
]
}
}
}
Validation Task
Validate data against rules:
{
"id": "validate-input",
"function": {
"name": "validation",
"input": {
"rules": [
{
"logic": {"!!": {"var": "data.required_field"}},
"message": "Required field is missing"
},
{
"logic": {">": [{"var": "data.amount"}, 0]},
"message": "Amount must be positive"
}
]
}
}
}
Custom Function Task
Call custom functions registered with the engine:
{
"id": "parse-message",
"function": {
"name": "parse_mt",
"input": {
"source": "data.raw_message",
"target": "data.SwiftMT"
}
}
}
Conditional Tasks
Tasks can have their own conditions:
{
"id": "map-optional-field",
"condition": {
"!!": {"var": "data.SwiftMT.fields.70.remittance_information"}
},
"function": {
"name": "map",
"input": {
"mappings": [
{
"path": "data.output.RmtInf.Ustrd",
"logic": {"var": "data.SwiftMT.fields.70.remittance_information"}
}
]
}
}
}
The task only executes if the condition evaluates to true.
Audit Trail
Every modification is recorded:
{
"audit_trail": [
{
"timestamp": "2025-01-15T10:30:00.123Z",
"workflow_id": "mt103-transform",
"task_id": "map-payment-info",
"path": "data.output.PmtId.InstrId",
"old_value": null,
"new_value": "REF123456"
},
{
"timestamp": "2025-01-15T10:30:00.125Z",
"workflow_id": "mt103-transform",
"task_id": "map-amount",
"path": "data.output.IntrBkSttlmAmt",
"old_value": null,
"new_value": {"Ccy": "USD", "value": "50000.00"}
}
]
}
Audit Trail Benefits
- Debugging: See exactly what changed and when
- Compliance: Complete transformation history
- Testing: Verify expected transformations occurred
- Monitoring: Track transformation patterns
Error Handling
Workflow-Level Handling
{
"id": "critical-workflow",
"error_handling": "stop",
"tasks": [/* ... */]
}
| Setting | Behavior |
|---|---|
"continue" | Log error, continue to next workflow |
"stop" | Halt processing, return error |
Task-Level Handling
{
"id": "optional-task",
"error_handling": "continue",
"function": {/* ... */}
}
Error Collection
Errors are collected in the context:
{
"errors": [
{
"workflow_id": "validation",
"task_id": "check-amount",
"code": "VALIDATION_FAILED",
"message": "Amount must be positive"
}
]
}
Performance Optimization
Pre-Compilation
All JSONLogic rules are compiled at startup:
Startup
│
▼
┌──────────────────┐
│ Load Workflows │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Compile All │ ← One-time cost
│ JSONLogic Rules │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Cache Compiled │
│ Rules in Memory │
└────────┬─────────┘
│
▼
Ready to Process
Runtime Efficiency
During message processing:
- No parsing of rule definitions
- Direct execution of compiled logic
- O(1) access to cached rules
Workflow Index
The workflow index registers all workflows:
// transform/index.json
{
"workflows": [
{"path": "00-detect-format.json"},
{"path": "outgoing/parse-mt.json"},
{"path": "outgoing/MT103/bah-mapping.json"},
{"path": "outgoing/MT103/document-mapping.json"},
{"path": "outgoing/combine-xml.json"},
{"path": "incoming/parse-mx.json"},
{"path": "incoming/pacs008/variant-detection.json"},
{"path": "incoming/pacs008/field-mapping.json"}
]
}
Quick Start: Run Reframe in 5 Minutes
Get the open source SWIFT MT to ISO 20022 transformation engine running locally.
Note: This guide uses the CBPR+ package (SWIFT MT ↔ ISO 20022). Reframe supports custom transformation packages for other formats.
Prerequisites
- Docker installed (Get Docker)
- curl or similar HTTP client
Step 1: Start Reframe
# Pull and run Reframe
docker run -d -p 3000:3000 --name reframe plasmatic/reframe:latest
# Verify it's running
curl http://localhost:3000/health
Expected response:
{
"status": "healthy",
"engines": {
"transform": "ready",
"generation": "ready",
"validation": "ready"
}
}
Step 2: Transform a Message (CBPR+ Example)
Transform an MT103 to ISO 20022 pacs.008 using the included CBPR+ package:
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{4:\n:20:REF123456\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/12345678\nACME CORPORATION\n123 MAIN STREET\nNEW YORK NY 10001\n:59:/98765432\nGLOBAL TRADING LTD\n456 HIGH STREET\nLONDON EC1A 1BB\n:71A:SHA\n-}"
}'
The response contains the transformed pacs.008 XML message.
Step 3: Generate a Sample Message
Generate a test MT103 message:
curl -X POST http://localhost:3000/api/generate \
-H "Content-Type: application/json" \
-d '{"message_type": "MT103", "scenario": "standard"}'
Step 4: Validate a Message
Validate any MT or ISO 20022 message:
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message": "<your message here>",
"business_validation": true
}'
Try the Playground
For a visual interface, use the interactive playground:
The playground lets you:
- Generate sample messages
- Transform between formats
- Validate messages
- See API requests and responses
What’s Next?
Common Issues
Port Already in Use
# Check what's using port 3000
lsof -i :3000
# Use a different port
docker run -p 8080:3000 plasmatic/reframe:latest
Container Not Starting
# Check container logs
docker logs reframe
# Run in foreground for debugging
docker run -p 3000:3000 plasmatic/reframe:latest
Connection Refused
Ensure Docker is running and the container is healthy:
docker ps
docker inspect reframe | grep Health
Your First Transformation
A step-by-step guide to understanding how Reframe transforms MT103 to ISO 20022 pacs.008.
What We’ll Cover
- Understanding the MT103 message structure
- Transforming MT103 to pacs.008
- Examining the transformation result
- Understanding field mappings
The MT103 Message
MT103 is SWIFT’s standard message for single customer credit transfers. Here’s a sample:
{1:F01BNPAFRPPXXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}
{4:
:20:REF123456
:23B:CRED
:32A:250115USD50000,00
:50K:/12345678
ACME CORPORATION
123 MAIN STREET
NEW YORK NY 10001
:59:/98765432
GLOBAL TRADING LTD
456 HIGH STREET
LONDON EC1A 1BB
:71A:SHA
-}
MT103 Structure
| Block/Tag | Content | Purpose |
|---|---|---|
| Block 1 | F01BNPAFRPPXXX... | Basic header - sender BIC |
| Block 2 | I103DEUTDEFFXXXX | Application header - receiver BIC |
| Block 3 | {121:...} | User header - UETR |
| Tag 20 | REF123456 | Transaction reference |
| Tag 23B | CRED | Bank operation code |
| Tag 32A | 250115USD50000,00 | Value date, currency, amount |
| Tag 50K | Account + Name + Address | Ordering customer (debtor) |
| Tag 59 | Account + Name + Address | Beneficiary (creditor) |
| Tag 71A | SHA | Charges (shared) |
Step 1: Send the Transformation Request
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}{4:\n:20:REF123456\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/12345678\nACME CORPORATION\n123 MAIN STREET\nNEW YORK NY 10001\n:59:/98765432\nGLOBAL TRADING LTD\n456 HIGH STREET\nLONDON EC1A 1BB\n:71A:SHA\n-}",
"validation": true
}'
Step 2: Examine the Response
The response contains the transformed pacs.008 message:
{
"status": "success",
"direction": "outgoing",
"source_type": "MT103",
"target_type": "pacs.008.001.12",
"message": "<?xml version=\"1.0\"?>...",
"timing_ms": 0.8
}
Step 3: Understanding the pacs.008 Output
The transformed ISO 20022 message has two parts:
Business Application Header (BAH)
<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
<Fr>
<FIId>
<FinInstnId>
<BICFI>BNPAFRPPXXX</BICFI>
</FinInstnId>
</FIId>
</Fr>
<To>
<FIId>
<FinInstnId>
<BICFI>DEUTDEFFXXX</BICFI>
</FinInstnId>
</FIId>
</To>
<BizMsgIdr>REF123456</BizMsgIdr>
<MsgDefIdr>pacs.008.001.12</MsgDefIdr>
<CreDt>2025-01-15T10:30:00Z</CreDt>
</AppHdr>
Document (pacs.008)
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>REF123456</MsgId>
<CreDtTm>2025-01-15T10:30:00Z</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<SttlmInf>
<SttlmMtd>INDA</SttlmMtd>
</SttlmInf>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<InstrId>REF123456</InstrId>
<EndToEndId>REF123456</EndToEndId>
<UETR>174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a</UETR>
</PmtId>
<IntrBkSttlmAmt Ccy="USD">50000.00</IntrBkSttlmAmt>
<IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
<ChrgBr>SHAR</ChrgBr>
<Dbtr>
<Nm>ACME CORPORATION</Nm>
<PstlAdr>
<AdrLine>123 MAIN STREET</AdrLine>
<AdrLine>NEW YORK NY 10001</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<Othr>
<Id>12345678</Id>
</Othr>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BICFI>BNPAFRPPXXX</BICFI>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BICFI>DEUTDEFFXXX</BICFI>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>GLOBAL TRADING LTD</Nm>
<PstlAdr>
<AdrLine>456 HIGH STREET</AdrLine>
<AdrLine>LONDON EC1A 1BB</AdrLine>
</PstlAdr>
</Cdtr>
<CdtrAcct>
<Id>
<Othr>
<Id>98765432</Id>
</Othr>
</Id>
</CdtrAcct>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
Field Mapping Summary
Here’s how key MT103 fields map to pacs.008:
| MT103 Field | pacs.008 Path | Example |
|---|---|---|
| Block 1 BIC | Fr/FIId/FinInstnId/BICFI | BNPAFRPPXXX |
| Block 2 BIC | To/FIId/FinInstnId/BICFI | DEUTDEFFXXX |
| Tag 20 | PmtId/InstrId | REF123456 |
| Tag 121 (UETR) | PmtId/UETR | 174d2c70-… |
| Tag 32A date | IntrBkSttlmDt | 2025-01-15 |
| Tag 32A amount | IntrBkSttlmAmt | 50000.00 |
| Tag 32A currency | IntrBkSttlmAmt/@Ccy | USD |
| Tag 50K name | Dbtr/Nm | ACME CORPORATION |
| Tag 50K account | DbtrAcct/Id/Othr/Id | 12345678 |
| Tag 59 name | Cdtr/Nm | GLOBAL TRADING LTD |
| Tag 59 account | CdtrAcct/Id/Othr/Id | 98765432 |
| Tag 71A | ChrgBr | SHA → SHAR |
Charge Bearer Mapping
The 71A tag maps to ISO 20022 charge bearer codes:
| MT (71A) | ISO 20022 | Meaning |
|---|---|---|
| SHA | SHAR | Shared between parties |
| OUR | DEBT | All charges to debtor |
| BEN | CRED | All charges to creditor |
Try It Yourself
Use the interactive playground to experiment:
Debug Mode
To see the transformation steps, add debug: true:
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "...",
"debug": true
}'
The debug response shows:
- Parsed input structure
- Each workflow that executed
- Intermediate transformation values
- Final output assembly
Reverse Transformation
Transform pacs.008 back to MT103:
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "<?xml version=\"1.0\"?>..."
}'
Reframe auto-detects the input format and applies the appropriate transformation direction.
See MT103 → pacs.008 Details →
CBPR+ Package: SWIFT MT to ISO 20022 Migration Guide
The free, open source CBPR+ transformation package for SWIFT MT to ISO 20022 migration with SR2025 compliance.
About This Package
The SWIFT CBPR+ Package is a free, open-source transformation package for Reframe. It provides:
- 41+ transformation scenarios for SWIFT MT ↔ ISO 20022
- SR2025 compliance for the November 2025 migration deadline
- Bidirectional support - convert in both directions
- 594 JSON rule files - fully auditable transformation logic
| GitHub | github.com/GoPlasmatic/reframe-package-swift-cbpr |
| License | Apache 2.0 (Free) |
| Version | 2.1.2 |
What is CBPR+?
CBPR+ (Cross-Border Payments and Reporting Plus) is SWIFT’s framework for the migration from MT messages to ISO 20022. It defines:
- Which ISO 20022 messages replace which MT messages
- Field mapping guidelines between formats
- Business rules and validation requirements
- Coexistence rules during the migration period
SR2025 Compliance
This CBPR+ package is fully compliant with SWIFT Standards Release 2025 (SR2025), which becomes mandatory in November 2025. Key SR2025 features:
- Business Application Header v3
- UETR (Unique End-to-End Transaction Reference) support
- Enhanced party identification with LEI
- Structured remittance information
- Updated message versions (pacs.008.001.12, pacs.009.001.11, etc.)
Supported Transformations
The CBPR+ package supports 41+ transformation scenarios across payment, status, and administrative messages.
Message Categories
| Category | Description | Examples |
|---|---|---|
| Customer Payments | Individual customer transfers | MT103 ↔ pacs.008 |
| FI Transfers | Bank-to-bank transfers | MT202 ↔ pacs.009 |
| Returns | Payment returns | MT103 RETN ↔ pacs.004 |
| Rejections | Payment rejections | MT103 REJT ↔ pacs.002 |
| Cancellations | Cancellation requests | MT192 ↔ camt.056 |
| Status | Payment status reports | MT199 ↔ camt.029 |
| Cash Management | Account statements | MT940 ↔ camt.053 |
Direction Terminology
| Term | Direction | Description |
|---|---|---|
| Outgoing | MT → MX | SWIFT MT converted to ISO 20022 |
| Incoming | MX → MT | ISO 20022 converted to SWIFT MT |
Package Structure
The CBPR+ package contains 594 JSON rule files organized by transformation type:
reframe-package-swift-cbpr/
├── reframe-package.json # Package metadata
│
├── transform/ # Transformation workflows
│ ├── outgoing/ # MT → ISO 20022
│ │ ├── MT103/ # Customer transfers
│ │ ├── MT202/ # FI transfers
│ │ ├── MT192/ # Cancellations
│ │ └── ...
│ │
│ └── incoming/ # ISO 20022 → MT
│ ├── pacs008/ # FIToFICustomerCreditTransfer
│ ├── pacs009/ # FIToFIFinancialInstitutionCreditTransfer
│ ├── camt056/ # FIToFIPaymentCancellationRequest
│ └── ...
│
├── validate/ # Validation rules
└── generate/ # Sample generation
Message Flow
Outgoing Flow (MT → ISO 20022)
MT103 Message
│
▼
┌─────────────────┐
│ 1. Parse MT │ Extract SWIFT blocks and fields
└────────┬────────┘
│
▼
┌─────────────────┐
│ 2. Detect Type │ Identify variant (standard/STP/REJT/RETN)
└────────┬────────┘
│
▼
┌─────────────────┐
│ 3. Apply Rules │ Execute CBPR+ mapping rules
└────────┬────────┘
│
▼
┌─────────────────┐
│ 4. Generate XML │ Create ISO 20022 envelope
└────────┬────────┘
│
▼
pacs.008 XML
Incoming Flow (ISO 20022 → MT)
pacs.008 XML
│
▼
┌─────────────────┐
│ 1. Parse XML │ Extract ISO 20022 structure
└────────┬────────┘
│
▼
┌─────────────────┐
│ 2. Detect MT │ Determine target MT type
└────────┬────────┘
│
▼
┌─────────────────┐
│ 3. Apply Rules │ Execute reverse mapping rules
└────────┬────────┘
│
▼
┌─────────────────┐
│ 4. Generate MT │ Create SWIFT message blocks
└────────┬────────┘
│
▼
MT103 Message
Key Concepts
Business Application Header (BAH)
ISO 20022 messages include a BAH with routing information:
<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
<Fr><FIId><FinInstnId><BICFI>SENDERXX</BICFI></FinInstnId></FIId></Fr>
<To><FIId><FinInstnId><BICFI>RECEIVERXX</BICFI></FinInstnId></FIId></To>
<BizMsgIdr>MSG123</BizMsgIdr>
<MsgDefIdr>pacs.008.001.12</MsgDefIdr>
<CreDt>2025-01-15T10:30:00Z</CreDt>
</AppHdr>
The BAH is generated from MT Block 1 and Block 2 information.
UETR (Unique End-to-End Transaction Reference)
UETR provides end-to-end tracking for payments:
- Format: UUID v4 (e.g.,
174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a) - In MT: Tag 121 in Block 3
- In ISO 20022:
PmtId/UETR
Service Level Codes
CBPR+ defines service levels for payment processing:
| Code | Name | Description |
|---|---|---|
| G001 | URGP | Urgent payment (high priority) |
| G002 | NURG | Normal urgent (standard) |
| G003 | SDVA | Same-day value |
| G004 | NORM | Normal (next-day) |
Try the Transformations
Interactive Playground
API Examples
# MT103 → pacs.008
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{"message": "{1:F01...}{2:I103...}{4:...}"}'
# pacs.008 → MT103
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{"message": "<?xml version=\"1.0\"?>..."}'
MT to ISO 20022 Transformations →
ISO 20022 to MT Transformations →
Message Catalog
Complete list of message types supported by the Reframe CBPR+ package.
Outgoing Transformations (MT → ISO 20022)
Customer Payments
| MT Type | ISO 20022 | Description |
|---|---|---|
| MT101 | pain.001 | Request for Transfer |
| MT103 | pacs.008 | Single Customer Credit Transfer |
| MT103 STP | pacs.008 | Straight-Through Processing variant |
| MT103 REJT | pacs.002 | Payment Rejection |
| MT103 RETN | pacs.004 | Payment Return |
Financial Institution Transfers
| MT Type | ISO 20022 | Description |
|---|---|---|
| MT200 | pacs.009 | Financial Institution Transfer (Own Account) |
| MT202 | pacs.009 | Financial Institution Transfer |
| MT202 COV | pacs.009 | Cover Payment |
| MT202 REJT | pacs.002 | FI Transfer Rejection |
| MT202 RETN | pacs.004 | FI Transfer Return |
| MT205 | pacs.009 | Financial Institution Transfer (Third Party) |
| MT205 COV | pacs.009 | Cover Payment (Third Party) |
| MT205 REJT | pacs.002 | FI Transfer Rejection |
| MT205 RETN | pacs.004 | FI Transfer Return |
Cancellation & Investigation
| MT Type | ISO 20022 | Description |
|---|---|---|
| MT192 | camt.056 | Request for Cancellation (Customer) |
| MT196 | camt.029 | Answer to Cancellation Request |
| MT292 | camt.056 | Request for Cancellation (FI) |
| MT296 | camt.029 | Answer to Cancellation Request (FI) |
Cash Management
| MT Type | ISO 20022 | Description |
|---|---|---|
| MT900 | camt.054 | Confirmation of Debit |
| MT910 | camt.054 | Confirmation of Credit |
| MT940 | camt.053 | Customer Statement |
| MT941 | camt.052 | Balance Report |
| MT942 | camt.052 | Interim Transaction Report |
Incoming Transformations (ISO 20022 → MT)
Payment Messages
| ISO 20022 | MT Type | Description |
|---|---|---|
| pain.001 | MT101 | CustomerCreditTransferInitiation |
| pacs.002 | MT103 REJT / MT202 REJT | FIToFIPaymentStatusReport |
| pacs.003 | MT104 | FIToFICustomerDirectDebit |
| pacs.004 | MT103 RETN / MT202 RETN | PaymentReturn |
| pacs.008 | MT103 | FIToFICustomerCreditTransfer |
| pacs.009 | MT202 / MT202 COV / MT205 | FIToFIFinancialInstitutionCreditTransfer |
| pacs.010 | MT204 | FIToFIDirectDebit |
Cash Management Messages
| ISO 20022 | MT Type | Description |
|---|---|---|
| camt.029 | MT196 / MT296 | ResolutionOfInvestigation |
| camt.052 | MT942 / MT941 | BankToCustomerAccountReport |
| camt.053 | MT940 | BankToCustomerStatement |
| camt.054 | MT900 / MT910 / MT103 / MT202 | BankToCustomerDebitCreditNotification |
| camt.056 | MT192 / MT292 | FIToFIPaymentCancellationRequest |
| camt.057 | MT210 | NotificationToReceive |
| camt.058 | Notification | NotificationToReceiveCancellationAdvice |
SR2025 New Messages
| ISO 20022 | MT Type | Description |
|---|---|---|
| camt.105 | MTn90 | ChargesPaymentNotification |
| camt.106 | MTn91 | ChargesPaymentRequest |
| camt.107 | MT110 | ChequePresentation |
| camt.108 | MT111 | ChequeCancellationOrStopRequest |
| camt.109 | MT112 | ChequeCancellationOrStopReport |
| admi.024 | MT199 | SystemEventNotification |
Message Type Details
pacs.008 - FIToFICustomerCreditTransfer
The core message for customer credit transfers.
Used for:
- Single customer payments
- Cross-border transfers
- Domestic high-value payments
Key elements:
- Group Header (GrpHdr)
- Credit Transfer Transaction Information (CdtTrfTxInf)
- Payment Identification
- Interbank Settlement Amount
- Debtor/Creditor Information
- Agent Chain
pacs.009 - FIToFIFinancialInstitutionCreditTransfer
Bank-to-bank transfers for treasury operations.
Used for:
- Bank treasury movements
- Cover payments
- Nostro/Vostro movements
Key elements:
- Group Header
- Credit Transfer Transaction Information
- Underlying Customer Credit Transfer (for covers)
camt.056 - FIToFIPaymentCancellationRequest
Request to cancel a previously sent payment.
Used for:
- Duplicate payment recall
- Fraudulent payment recall
- Technical error correction
Key elements:
- Assignment information
- Original message details
- Cancellation reason
Version Support
The CBPR+ package supports the latest ISO 20022 message versions:
| Message | Version |
|---|---|
| head.001 | 001.03 |
| pacs.002 | 001.14 |
| pacs.004 | 001.13 |
| pacs.008 | 001.12 |
| pacs.009 | 001.11 |
| camt.029 | 001.13 |
| camt.052 | 001.12 |
| camt.053 | 001.12 |
| camt.054 | 001.12 |
| camt.056 | 001.12 |
MT to ISO 20022 Transformations
Converting SWIFT MT messages to ISO 20022 format.
Overview
Outgoing transformations convert legacy SWIFT MT messages to ISO 20022 XML format. This is the primary direction for institutions migrating to ISO 20022 for cross-border payments.
Transformation Pipeline
Every MT → ISO 20022 transformation follows this pipeline:
┌─────────────────────────────────────────────────────────────┐
│ MT → ISO 20022 Pipeline │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. Parse MT Priority 1 │
│ Extract blocks, tags, and field values │
│ │
│ 2. Detect Message Type Priority 2 │
│ Identify MT variant (standard, STP, REJT, RETN) │
│ │
│ 3. Map BAH Priority 3 │
│ Create Business Application Header from MT headers │
│ │
│ 4. Pre-conditions Priority 4 │
│ Validate business rules before transformation │
│ │
│ 5. Map Document Priority 5 │
│ Transform MT fields to ISO 20022 document structure │
│ │
│ 6. Post-conditions Priority 6 │
│ Validate output compliance │
│ │
│ 7. Combine XML Priority 10 │
│ Generate final ISO 20022 XML envelope │
│ │
└─────────────────────────────────────────────────────────────┘
Supported Transformations
Customer Payments
| Source | Target | Description | Details |
|---|---|---|---|
| MT103 | pacs.008 | Customer Credit Transfer | View → |
| MT103 STP | pacs.008 | Straight-Through Processing | |
| MT103 REJT | pacs.002 | Payment Rejection | |
| MT103 RETN | pacs.004 | Payment Return |
Financial Institution Transfers
| Source | Target | Description |
|---|---|---|
| MT200 | pacs.009 | Own Account Transfer |
| MT202 | pacs.009 | General FI Transfer |
| MT202 COV | pacs.009 | Cover Payment |
| MT202 REJT | pacs.002 | FI Transfer Rejection |
| MT202 RETN | pacs.004 | FI Transfer Return |
| MT205 | pacs.009 | Third Party FI Transfer |
| MT205 COV | pacs.009 | Cover Payment (Third Party) |
Cancellation & Investigation
| Source | Target | Description |
|---|---|---|
| MT192 | camt.056 | Customer Payment Cancellation |
| MT196 | camt.029 | Cancellation Response |
| MT292 | camt.056 | FI Payment Cancellation |
| MT296 | camt.029 | FI Cancellation Response |
Cash Management
| Source | Target | Description |
|---|---|---|
| MT900 | camt.054 | Debit Confirmation |
| MT910 | camt.054 | Credit Confirmation |
Common Field Mappings
These mappings apply across multiple MT → ISO 20022 transformations:
Header Mappings
| MT Source | ISO 20022 Target | Description |
|---|---|---|
| Block 1 BIC | AppHdr/Fr/FIId/FinInstnId/BICFI | Sender identification |
| Block 2 BIC | AppHdr/To/FIId/FinInstnId/BICFI | Receiver identification |
| Tag 20 | AppHdr/BizMsgIdr | Message identifier |
| Tag 121 (Block 3) | PmtId/UETR | End-to-end tracking |
Amount Mappings
| MT Source | ISO 20022 Target | Notes |
|---|---|---|
| Tag 32A Date | IntrBkSttlmDt | YYMMDD → YYYY-MM-DD |
| Tag 32A Currency | IntrBkSttlmAmt/@Ccy | 3-letter code |
| Tag 32A Amount | IntrBkSttlmAmt | Remove comma separator |
Party Mappings
| MT Source | ISO 20022 Target | Notes |
|---|---|---|
| Tag 50K/50F | Dbtr | Ordering customer |
| Tag 50K Account | DbtrAcct/Id/Othr/Id | Account number |
| Tag 59/59A | Cdtr | Beneficiary |
| Tag 59 Account | CdtrAcct/Id/Othr/Id | Account number |
Agent Mappings
| MT Source | ISO 20022 Target | Notes |
|---|---|---|
| Tag 52A | DbtrAgt | Debtor’s bank |
| Tag 53A/53B | InstgAgt or IntrmyAgt1 | Intermediary |
| Tag 54A | IntrmyAgt1 | Intermediary |
| Tag 57A | CdtrAgt | Creditor’s bank |
Charge Bearer Mapping
| MT (Tag 71A) | ISO 20022 | Code |
|---|---|---|
| SHA | SHAR | Shared |
| OUR | DEBT | All charges to debtor |
| BEN | CRED | All charges to creditor |
Business Rules
Service Level Determination
The CBPR+ service level is determined from MT fields:
{
"if": [
{"==": [{"var": "fields.23E.instruction_code"}, "URGP"]},
"G001",
{"if": [
{"==": [{"var": "fields.23B.bank_operation_code"}, "SPAY"]},
"G003",
"G002"
]}
]
}
| MT Indicator | Service Level | Priority |
|---|---|---|
| 23E: URGP | G001 | Urgent |
| 23B: SPAY | G003 | Same-day |
| Default | G002 | Normal |
UETR Handling
If Tag 121 exists in Block 3, it’s used as the UETR. Otherwise, a new UUID is generated.
Date Conversion
MT dates (YYMMDD) are converted to ISO format (YYYY-MM-DD):
| MT | ISO 20022 |
|---|---|
| 250115 | 2025-01-15 |
| 991231 | 2099-12-31 |
Example Transformation
Input: MT103
{1:F01BNPAFRPPXXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}
{4:
:20:REF123456
:23B:CRED
:32A:250115USD50000,00
:50K:/12345678
ACME CORPORATION
:59:/98765432
GLOBAL TRADING LTD
:71A:SHA
-}
Output: pacs.008
<?xml version="1.0"?>
<BizMsg xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
<AppHdr>
<Fr><FIId><FinInstnId><BICFI>BNPAFRPPXXX</BICFI></FinInstnId></FIId></Fr>
<To><FIId><FinInstnId><BICFI>DEUTDEFFXXX</BICFI></FinInstnId></FIId></To>
<BizMsgIdr>REF123456</BizMsgIdr>
<MsgDefIdr>pacs.008.001.12</MsgDefIdr>
</AppHdr>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
<FIToFICstmrCdtTrf>
<CdtTrfTxInf>
<PmtId>
<InstrId>REF123456</InstrId>
<UETR>174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a</UETR>
</PmtId>
<IntrBkSttlmAmt Ccy="USD">50000.00</IntrBkSttlmAmt>
<IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
<ChrgBr>SHAR</ChrgBr>
<Dbtr><Nm>ACME CORPORATION</Nm></Dbtr>
<DbtrAcct><Id><Othr><Id>12345678</Id></Othr></Id></DbtrAcct>
<Cdtr><Nm>GLOBAL TRADING LTD</Nm></Cdtr>
<CdtrAcct><Id><Othr><Id>98765432</Id></Othr></Id></CdtrAcct>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
</BizMsg>
Try It
MT103 → pacs.008 Transformation
Complete guide to transforming SWIFT MT103 to ISO 20022 pacs.008.
Overview
MT103 (Single Customer Credit Transfer) is the most common SWIFT message type. It transforms to pacs.008 (FIToFICustomerCreditTransfer) in ISO 20022.
| Attribute | Value |
|---|---|
| Source Message | MT103 |
| Target Message | pacs.008.001.12 |
| Direction | Outgoing (MT → MX) |
| Category | Customer Payments |
| SR2025 | Fully compliant |
Message Structure Comparison
MT103 Structure
{1:F01...} Basic Header
{2:I103...} Application Header
{3:{121:...}} User Header (UETR)
{4: Text Block
:20: Transaction Reference
:23B: Bank Operation Code
:32A: Value Date/Currency/Amount
:50K: Ordering Customer
:52A: Ordering Institution
:53A: Sender's Correspondent
:54A: Receiver's Correspondent
:56A: Intermediary
:57A: Account With Institution
:59: Beneficiary
:70: Remittance Information
:71A: Details of Charges
:71F: Sender's Charges
:71G: Receiver's Charges
:72: Sender to Receiver Info
:77B: Regulatory Reporting
-}
pacs.008 Structure
<Document>
<FIToFICstmrCdtTrf>
<GrpHdr> Group Header
<MsgId> Message Identification
<CreDtTm> Creation Date Time
<NbOfTxs> Number of Transactions
<SttlmInf> Settlement Information
</GrpHdr>
<CdtTrfTxInf> Credit Transfer Transaction
<PmtId> Payment Identification
<PmtTpInf> Payment Type Information
<IntrBkSttlmAmt> Interbank Settlement Amount
<IntrBkSttlmDt> Interbank Settlement Date
<ChrgBr> Charge Bearer
<Dbtr> Debtor
<DbtrAcct> Debtor Account
<DbtrAgt> Debtor Agent
<CdtrAgt> Creditor Agent
<Cdtr> Creditor
<CdtrAcct> Creditor Account
<RmtInf> Remittance Information
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
Complete Field Mapping Table
Header Mappings
| MT Field | ISO 20022 Path | Rule | Example |
|---|---|---|---|
| Block 1 BIC | AppHdr/Fr/FIId/FinInstnId/BICFI | Direct | BNPAFRPPXXX |
| Block 2 BIC | AppHdr/To/FIId/FinInstnId/BICFI | Direct | DEUTDEFFXXX |
| Tag 20 | AppHdr/BizMsgIdr | Direct | REF123456 |
| Tag 20 | GrpHdr/MsgId | Direct | REF123456 |
| Tag 20 | PmtId/InstrId | Direct | REF123456 |
| Tag 121 | PmtId/UETR | Direct | UUID |
Amount & Date Mappings
| MT Field | ISO 20022 Path | Rule | Example |
|---|---|---|---|
| Tag 32A (date) | IntrBkSttlmDt | YYMMDD → YYYY-MM-DD | 250115 → 2025-01-15 |
| Tag 32A (currency) | IntrBkSttlmAmt/@Ccy | Direct | USD |
| Tag 32A (amount) | IntrBkSttlmAmt | Remove comma | 50000,00 → 50000.00 |
| Tag 33B (currency) | InstdAmt/@Ccy | Direct | EUR |
| Tag 33B (amount) | InstdAmt | Remove comma | 45000,00 → 45000.00 |
| Tag 36 | XchgRate | Direct | 1.1234 |
Ordering Customer (Debtor) Mappings
| MT Field | ISO 20022 Path | Notes |
|---|---|---|
| Tag 50K Line 1 (with /) | DbtrAcct/Id/Othr/Id | Account number |
| Tag 50K Name | Dbtr/Nm | Customer name |
| Tag 50K Address | Dbtr/PstlAdr/AdrLine | Address lines |
| Tag 50F /1 | Dbtr/Nm | Structured name |
| Tag 50F /2 | Dbtr/PstlAdr/StrtNm | Street |
| Tag 50F /3 | Dbtr/PstlAdr/TwnNm | Town |
| Tag 50F /4 | Dbtr/PstlAdr/Ctry | Country |
Beneficiary (Creditor) Mappings
| MT Field | ISO 20022 Path | Notes |
|---|---|---|
| Tag 59 Line 1 (with /) | CdtrAcct/Id/Othr/Id | Account number |
| Tag 59 Name | Cdtr/Nm | Beneficiary name |
| Tag 59 Address | Cdtr/PstlAdr/AdrLine | Address lines |
| Tag 59A | Cdtr/Id/OrgId/AnyBIC | BIC identification |
| Tag 59F /1 | Cdtr/Nm | Structured name |
Agent (Bank) Mappings
| MT Field | ISO 20022 Path | Notes |
|---|---|---|
| Tag 52A | DbtrAgt/FinInstnId/BICFI | Ordering institution |
| Tag 52D | DbtrAgt/FinInstnId/Nm + PstlAdr | Name and address |
| Tag 53A | InstgAgt/FinInstnId/BICFI | Sender’s correspondent |
| Tag 53B | InstgAgt/FinInstnId/ClrSysMmbId | Clearing system |
| Tag 54A | IntrmyAgt1/FinInstnId/BICFI | Receiver’s correspondent |
| Tag 56A | IntrmyAgt2/FinInstnId/BICFI | Intermediary |
| Tag 57A | CdtrAgt/FinInstnId/BICFI | Account with institution |
| Tag 57D | CdtrAgt/FinInstnId/Nm + PstlAdr | Name and address |
Charges Mappings
| MT Field | ISO 20022 Path | Mapping |
|---|---|---|
| Tag 71A: SHA | ChrgBr | SHAR |
| Tag 71A: OUR | ChrgBr | DEBT |
| Tag 71A: BEN | ChrgBr | CRED |
| Tag 71F | ChrgsInf/Amt + Agt | Sender’s charges |
| Tag 71G | ChrgsInf/Amt + Agt | Receiver’s charges |
Remittance & Regulatory
| MT Field | ISO 20022 Path | Notes |
|---|---|---|
| Tag 70 | RmtInf/Ustrd | Unstructured remittance |
| Tag 72 | InstrForCdtrAgt | Sender to receiver info |
| Tag 77B | RgltryRptg | Regulatory reporting |
Business Rules Applied
Service Level Determination
{
"path": "data.output.PmtTpInf.SvcLvl.Cd",
"logic": {
"if": [
{"==": [{"var": "data.SwiftMT.fields.23E.instruction_code"}, "URGP"]},
"G001",
{"if": [
{"==": [{"var": "data.SwiftMT.fields.23B.bank_operation_code"}, "SPAY"]},
"G003",
"G002"
]}
]
}
}
Settlement Method
{
"path": "data.output.GrpHdr.SttlmInf.SttlmMtd",
"logic": {
"if": [
{"!!": {"var": "data.SwiftMT.fields.53A"}},
"COVE",
"INDA"
]
}
}
Charge Bearer Conversion
{
"path": "data.output.ChrgBr",
"logic": {
"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
"SHAR",
{"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
"DEBT",
"CRED"
]}
]
}
}
Complete Example
Input: MT103
{1:F01BNPAFRPPXXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}
{4:
:20:REF123456789
:23B:CRED
:32A:250115USD50000,00
:50K:/12345678901234
ACME INTERNATIONAL CORP
123 BUSINESS AVENUE
NEW YORK NY 10001
:52A:CITIUS33XXX
:57A:COBADEFFXXX
:59:/DE89370400440532013000
GLOBAL TRADING GMBH
MUSTERSTRASSE 123
60329 FRANKFURT
:70:/INV/2025-001
PAYMENT FOR INVOICE
:71A:SHA
:72:/REC/PAYMENT
-}
Output: pacs.008
<?xml version="1.0" encoding="UTF-8"?>
<BizMsg xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
<AppHdr>
<Fr>
<FIId>
<FinInstnId>
<BICFI>BNPAFRPPXXX</BICFI>
</FinInstnId>
</FIId>
</Fr>
<To>
<FIId>
<FinInstnId>
<BICFI>DEUTDEFFXXX</BICFI>
</FinInstnId>
</FIId>
</To>
<BizMsgIdr>REF123456789</BizMsgIdr>
<MsgDefIdr>pacs.008.001.12</MsgDefIdr>
<CreDt>2025-01-15T10:30:00Z</CreDt>
</AppHdr>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>REF123456789</MsgId>
<CreDtTm>2025-01-15T10:30:00Z</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<SttlmInf>
<SttlmMtd>INDA</SttlmMtd>
</SttlmInf>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<InstrId>REF123456789</InstrId>
<EndToEndId>REF123456789</EndToEndId>
<UETR>174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a</UETR>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>G002</Cd>
</SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="USD">50000.00</IntrBkSttlmAmt>
<IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
<ChrgBr>SHAR</ChrgBr>
<Dbtr>
<Nm>ACME INTERNATIONAL CORP</Nm>
<PstlAdr>
<AdrLine>123 BUSINESS AVENUE</AdrLine>
<AdrLine>NEW YORK NY 10001</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<Othr>
<Id>12345678901234</Id>
</Othr>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BICFI>CITIUS33XXX</BICFI>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BICFI>COBADEFFXXX</BICFI>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>GLOBAL TRADING GMBH</Nm>
<PstlAdr>
<AdrLine>MUSTERSTRASSE 123</AdrLine>
<AdrLine>60329 FRANKFURT</AdrLine>
</PstlAdr>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>DE89370400440532013000</IBAN>
</Id>
</CdtrAcct>
<InstrForCdtrAgt>
<InstrInf>PAYMENT</InstrInf>
</InstrForCdtrAgt>
<RmtInf>
<Ustrd>/INV/2025-001 PAYMENT FOR INVOICE</Ustrd>
</RmtInf>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
</BizMsg>
Variants
MT103 STP
Straight-Through Processing variant with BIC-only agent identification:
- Same mapping as standard MT103
- Tag 119: STP in Block 3
- All agents identified by BIC (no name/address)
MT103 REJT
Payment rejection (transformed to pacs.002):
- Block 2 contains
103with REJT indicator - Includes original message reference
- Rejection reason code
MT103 RETN
Payment return (transformed to pacs.004):
- Indicates returned payment
- Contains reason for return
- May include charges information
Try It
API Example
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}{4:\n:20:REF123456789\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/12345678901234\nACME INTERNATIONAL CORP\n:59:/DE89370400440532013000\nGLOBAL TRADING GMBH\n:71A:SHA\n-}",
"validation": true
}'
Back to MT → ISO 20022 Overview →
ISO 20022 to MT Transformations
Converting ISO 20022 messages to SWIFT MT format.
Overview
Incoming transformations convert ISO 20022 XML messages to legacy SWIFT MT format. This direction supports:
- Systems that haven’t migrated to ISO 20022
- Legacy downstream applications
- Parallel running during migration
- Fallback scenarios
Transformation Pipeline
Every ISO 20022 → MT transformation follows this pipeline:
┌─────────────────────────────────────────────────────────────┐
│ ISO 20022 → MT Pipeline │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. Parse XML Priority 1 │
│ Extract ISO 20022 structure to JSON │
│ │
│ 2. Detect Target MT Priority 2 │
│ Determine appropriate MT message type │
│ │
│ 3. Pre-conditions Priority 3 │
│ Validate transformation feasibility │
│ │
│ 4. Map Headers Priority 4 │
│ Construct MT Block 1, 2, 3 │
│ │
│ 5. Map Fields Priority 5-9 │
│ Transform ISO 20022 elements to MT tags │
│ │
│ 6. Post-conditions Priority 10 │
│ Validate MT structure and assemble │
│ │
└─────────────────────────────────────────────────────────────┘
Supported Transformations
Payment Messages
| Source | Target | Description |
|---|---|---|
| pain.001 | MT101 | Customer Credit Transfer Initiation |
| pacs.002 | MT103 REJT / MT202 REJT | Payment Status Report |
| pacs.003 | MT104 | Direct Debit |
| pacs.004 | MT103 RETN / MT202 RETN | Payment Return |
| pacs.008 | MT103 | Customer Credit Transfer |
| pacs.009 | MT202 / MT202 COV / MT205 | FI Credit Transfer |
| pacs.010 | MT204 | Financial Institution Direct Debit |
Cash Management Messages
| Source | Target | Description |
|---|---|---|
| camt.029 | MT196 / MT296 | Resolution of Investigation |
| camt.052 | MT942 / MT941 | Account Report |
| camt.053 | MT940 | Bank Statement |
| camt.054 | MT900 / MT910 | Debit/Credit Notification |
| camt.056 | MT192 / MT292 | Cancellation Request |
| camt.057 | MT210 | Notification to Receive |
SR2025 Messages
| Source | Target | Description |
|---|---|---|
| camt.105 | MTn90 | Charges Payment Notification |
| camt.106 | MTn91 | Charges Payment Request |
| camt.107 | MT110 | Cheque Presentation |
| camt.108 | MT111 | Cheque Cancellation Request |
| camt.109 | MT112 | Cheque Cancellation Report |
| admi.024 | MT199 | System Event Notification |
Target MT Detection
The target MT type is determined by analyzing the ISO 20022 message:
pacs.008 → MT Detection
{
"if": [
{"!!": {"var": "data.MX.UndrlygCstmrCdtTrf"}},
"MT103",
{"if": [
{"==": [{"var": "data.MX.PmtTpInf.LclInstrm.Prtry"}, "COVER"]},
"MT202COV",
"MT103"
]}
]
}
pacs.009 → MT Detection
| Condition | Target MT |
|---|---|
| Has UnderlyingCustomerCreditTransfer | MT202 COV |
| InterbankSettlement only | MT202 |
| Third party indicator | MT205 |
camt.054 → MT Detection
| Condition | Target MT |
|---|---|
| Debit entry | MT900 |
| Credit entry | MT910 |
| Multiple entries | Multiple MTs |
Common Field Mappings
Header Generation
| ISO 20022 Source | MT Target | Notes |
|---|---|---|
AppHdr/Fr/FIId/FinInstnId/BICFI | Block 1 BIC | Sender |
AppHdr/To/FIId/FinInstnId/BICFI | Block 2 BIC | Receiver |
PmtId/UETR | Block 3 Tag 121 | End-to-end tracking |
AppHdr/BizMsgIdr | Tag 20 | Reference |
Amount Mapping
| ISO 20022 Source | MT Target | Notes |
|---|---|---|
IntrBkSttlmDt | Tag 32A (date) | YYYY-MM-DD → YYMMDD |
IntrBkSttlmAmt/@Ccy | Tag 32A (currency) | 3-letter code |
IntrBkSttlmAmt | Tag 32A (amount) | Add comma separator |
Party Mapping
| ISO 20022 Source | MT Target | Notes |
|---|---|---|
Dbtr/Nm | Tag 50K Line 1 | Debtor name |
Dbtr/PstlAdr/AdrLine | Tag 50K Lines 2-4 | Address |
DbtrAcct/Id/IBAN | Tag 50K Account | With / prefix |
DbtrAcct/Id/Othr/Id | Tag 50K Account | With / prefix |
Cdtr/Nm | Tag 59 Line 1 | Creditor name |
CdtrAcct/Id/IBAN | Tag 59 Account | With / prefix |
Agent Mapping
| ISO 20022 Source | MT Target | Notes |
|---|---|---|
DbtrAgt/FinInstnId/BICFI | Tag 52A | Debtor’s bank |
CdtrAgt/FinInstnId/BICFI | Tag 57A | Creditor’s bank |
IntrmyAgt1/FinInstnId/BICFI | Tag 56A | Intermediary |
Charge Bearer Mapping
| ISO 20022 | MT (Tag 71A) |
|---|---|
| SHAR | SHA |
| DEBT | OUR |
| CRED | BEN |
Data Truncation Rules
MT messages have field length limits. ISO 20022 data is truncated when necessary:
| MT Field | Max Length | Truncation Rule |
|---|---|---|
| Tag 20 | 16 chars | Truncate right |
| Tag 50K/59 name | 35 chars | Truncate right |
| Tag 50K/59 address | 35 chars/line | Truncate per line |
| Tag 70 | 4 x 35 chars | Truncate total |
| Tag 72 | 6 x 35 chars | Truncate total |
Example Transformation
Input: pacs.008
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>MSG123456789</MsgId>
<CreDtTm>2025-01-15T10:30:00Z</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<SttlmInf><SttlmMtd>INDA</SttlmMtd></SttlmInf>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<InstrId>INSTR123</InstrId>
<EndToEndId>E2E123</EndToEndId>
<UETR>174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a</UETR>
</PmtId>
<IntrBkSttlmAmt Ccy="EUR">25000.00</IntrBkSttlmAmt>
<IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
<ChrgBr>SHAR</ChrgBr>
<Dbtr><Nm>SENDER COMPANY</Nm></Dbtr>
<DbtrAcct><Id><IBAN>FR7630006000011234567890189</IBAN></Id></DbtrAcct>
<DbtrAgt><FinInstnId><BICFI>BNPAFRPPXXX</BICFI></FinInstnId></DbtrAgt>
<CdtrAgt><FinInstnId><BICFI>DEUTDEFFXXX</BICFI></FinInstnId></CdtrAgt>
<Cdtr><Nm>RECEIVER GMBH</Nm></Cdtr>
<CdtrAcct><Id><IBAN>DE89370400440532013000</IBAN></Id></CdtrAcct>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
Output: MT103
{1:F01BNPAFRPPXXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}
{4:
:20:INSTR123
:23B:CRED
:32A:250115EUR25000,00
:50K:/FR7630006000011234567890189
SENDER COMPANY
:57A:DEUTDEFFXXX
:59:/DE89370400440532013000
RECEIVER GMBH
:71A:SHA
-}
Try It
API Example
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "<?xml version=\"1.0\"?><Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12\">...</Document>"
}'
The API automatically detects ISO 20022 input and applies the appropriate reverse transformation.
SR2025 Compliance
SWIFT Standards Release 2025 compliance in Reframe.
Overview
SR2025 (Standards Release 2025) is SWIFT’s mandatory update that becomes effective in November 2025. It introduces:
- Updated ISO 20022 message versions
- Business Application Header v3
- Enhanced data requirements
- New message types for cash management
Reframe’s CBPR+ package is fully SR2025 compliant.
Message Version Support
Payment Messages
| Message | SR2025 Version | Previous Version |
|---|---|---|
| pacs.002 | 001.14 | 001.12 |
| pacs.004 | 001.13 | 001.11 |
| pacs.008 | 001.12 | 001.10 |
| pacs.009 | 001.11 | 001.09 |
| pacs.010 | 001.06 | 001.04 |
Cash Management Messages
| Message | SR2025 Version | Previous Version |
|---|---|---|
| camt.029 | 001.13 | 001.11 |
| camt.052 | 001.12 | 001.10 |
| camt.053 | 001.12 | 001.10 |
| camt.054 | 001.12 | 001.10 |
| camt.056 | 001.12 | 001.10 |
| camt.057 | 001.08 | 001.06 |
New SR2025 Messages
| Message | Version | Description |
|---|---|---|
| camt.105 | 001.02 | Charges Payment Notification |
| camt.106 | 001.02 | Charges Payment Request |
| camt.107 | 001.02 | Cheque Presentation Notification |
| camt.108 | 001.02 | Cheque Cancellation or Stop Request |
| camt.109 | 001.02 | Cheque Cancellation or Stop Report |
| admi.024 | 001.01 | System Event Notification |
Business Application Header v3
SR2025 uses BAH version 3 (head.001.001.03) with enhanced features:
<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
<Fr>
<FIId>
<FinInstnId>
<BICFI>BNPAFRPPXXX</BICFI>
<LEI>9695005MSX1OYEMGDF46</LEI>
</FinInstnId>
</FIId>
</Fr>
<To>
<FIId>
<FinInstnId>
<BICFI>DEUTDEFFXXX</BICFI>
<LEI>7LTWFZYICNSX8D621K86</LEI>
</FinInstnId>
</FIId>
</To>
<BizMsgIdr>MSG123456789</BizMsgIdr>
<MsgDefIdr>pacs.008.001.12</MsgDefIdr>
<BizSvc>swift.cbprplus.02</BizSvc>
<CreDt>2025-01-15T10:30:00Z</CreDt>
<Prty>NORM</Prty>
</AppHdr>
BAH v3 Enhancements
| Field | Description | Notes |
|---|---|---|
LEI | Legal Entity Identifier | 20-character code |
BizSvc | Business Service | CBPR+ service identifier |
Prty | Priority | HIGH, NORM, or empty |
PssblDplct | Possible Duplicate | Boolean flag |
UETR Requirements
The UETR (Unique End-to-End Transaction Reference) is mandatory for all CBPR+ payments:
Format
- UUID version 4
- 36 characters including hyphens
- Example:
174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a
In Messages
- ISO 20022:
PmtId/UETR - SWIFT MT: Block 3, Tag 121
Reframe Handling
{
"path": "data.output.PmtId.UETR",
"logic": {
"or": [
{"var": "data.SwiftMT.block3.121"},
{"uuid": []}
]
}
}
If the source MT message contains Tag 121, it’s preserved. Otherwise, a new UUID is generated.
Enhanced Party Identification
SR2025 requires richer party identification:
Legal Entity Identifier (LEI)
<Dbtr>
<Nm>ACME CORPORATION</Nm>
<Id>
<OrgId>
<LEI>5493001KJTIIGC8Y1R12</LEI>
</OrgId>
</Id>
</Dbtr>
BIC + BEI Identification
<DbtrAgt>
<FinInstnId>
<BICFI>BNPAFRPPXXX</BICFI>
</FinInstnId>
</DbtrAgt>
Structured Address
SR2025 encourages structured addresses over free-form:
<PstlAdr>
<StrtNm>123 MAIN STREET</StrtNm>
<BldgNb>SUITE 500</BldgNb>
<PstCd>10001</PstCd>
<TwnNm>NEW YORK</TwnNm>
<CtrySubDvsn>NY</CtrySubDvsn>
<Ctry>US</Ctry>
</PstlAdr>
Service Level Codes
CBPR+ service levels for SR2025:
| Code | Name | Description | SLA |
|---|---|---|---|
| G001 | URGP | Urgent Payment | Immediate |
| G002 | NURG | Normal Urgent | Same day |
| G003 | SDVA | Same Day Value | End of day |
| G004 | NORM | Normal | Next day |
Mapping from MT
{
"if": [
{"==": [{"var": "fields.23E"}, "URGP"]},
"G001",
{"if": [
{"==": [{"var": "fields.23B"}, "SPAY"]},
"G003",
"G002"
]}
]
}
Structured Remittance
SR2025 supports structured remittance information:
Structured Format
<RmtInf>
<Strd>
<RfrdDocInf>
<Tp>
<CdOrPrtry>
<Cd>CINV</Cd>
</CdOrPrtry>
</Tp>
<Nb>INV-2025-001234</Nb>
<RltdDt>2025-01-10</RltdDt>
</RfrdDocInf>
<RfrdDocAmt>
<DuePyblAmt Ccy="USD">50000.00</DuePyblAmt>
</RfrdDocAmt>
</Strd>
</RmtInf>
Document Types
| Code | Description |
|---|---|
| CINV | Commercial Invoice |
| CREN | Credit Note |
| DEBN | Debit Note |
| SOAC | Statement of Account |
| DISP | Dispatch Advice |
Regulatory Reporting
Enhanced regulatory reporting for SR2025:
<RgltryRptg>
<DbtCdtRptgInd>DEBT</DbtCdtRptgInd>
<Authrty>
<Nm>CENTRAL BANK</Nm>
<Ctry>US</Ctry>
</Authrty>
<Dtls>
<Tp>CRED</Tp>
<Cd>GOODS</Cd>
<Amt Ccy="USD">50000.00</Amt>
<Inf>PAYMENT FOR GOODS</Inf>
</Dtls>
</RgltryRptg>
Validation Rules
Reframe enforces SR2025 validation rules:
Mandatory Fields
| Message | Required Fields |
|---|---|
| pacs.008 | UETR, IntrBkSttlmAmt, IntrBkSttlmDt, ChrgBr |
| pacs.009 | UETR, IntrBkSttlmAmt, IntrBkSttlmDt |
| camt.056 | OrgnlMsgId, OrgnlMsgNmId, CxlRsnInf |
Format Validations
| Field | Rule |
|---|---|
| BIC | 8 or 11 characters |
| LEI | 20 characters |
| UETR | UUID v4 format |
| IBAN | Country-specific length |
| Amount | Max 18 digits, 5 decimals |
Coexistence Period
During the SR2025 migration, Reframe supports:
Bidirectional Translation
- Convert MT messages to SR2025-compliant ISO 20022
- Convert ISO 20022 back to MT for legacy systems
Version Handling
- Accept older ISO 20022 versions
- Output latest SR2025 versions
- Preserve data through translation
Feature Degradation
- LEI stripped when converting to MT
- Structured addresses converted to free-form
- Structured remittance converted to unstructured
Testing SR2025 Compliance
Generate SR2025 Messages
curl -X POST http://localhost:3000/api/generate \
-H "Content-Type: application/json" \
-d '{"message_type": "pacs.008", "scenario": "sr2025_standard"}'
Validate SR2025 Compliance
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message": "<ISO 20022 message>",
"business_validation": true
}'
Sample Generation
Generate valid test messages for development, testing, and certification.
Overview
Reframe can generate sample SWIFT MT and ISO 20022 messages for any supported message type. Generated messages are:
- Valid: Pass schema and business validation
- Realistic: Use plausible data values
- Configurable: Multiple scenarios per message type
- Reproducible: Same scenario produces consistent structure
API Usage
Generate a Sample Message
curl -X POST http://localhost:3000/api/generate \
-H "Content-Type: application/json" \
-d '{
"message_type": "MT103",
"scenario": "standard"
}'
Response
{
"status": "success",
"message_type": "MT103",
"scenario": "standard",
"message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}...",
"metadata": {
"generated_at": "2025-01-15T10:30:00Z",
"package": "swift-cbpr-mt-mx",
"version": "2.1.2"
}
}
Supported Types
For the complete list of supported message types and scenarios, see Generate API Reference →
Scenarios
Scenarios define different variations of a message type:
MT103 Scenarios
standard: Basic customer credit transfer
{"message_type": "MT103", "scenario": "standard"}
high_value: Large amount transfer with additional details
{"message_type": "MT103", "scenario": "high_value"}
remittance: Includes detailed remittance information
{"message_type": "MT103", "scenario": "remittance"}
pacs.008 Scenarios
standard: Basic ISO 20022 credit transfer
{"message_type": "pacs.008", "scenario": "standard"}
high_value: Large amount with full party details
{"message_type": "pacs.008", "scenario": "high_value"}
Data Generation
Sample messages use realistic generated data:
Financial Data
- BICs: Valid SWIFT BIC codes
- IBANs: Country-appropriate format
- Amounts: Realistic ranges by scenario
- Currencies: Major currencies (USD, EUR, GBP, etc.)
Party Information
- Names: Company names for corporate payments
- Addresses: Valid postal addresses
- References: Realistic transaction references
Dates
- Value Date: Near future dates
- Creation Time: Current timestamp
- Statement Dates: Recent date ranges
Use Cases
Development Testing
Generate messages for unit and integration tests:
# Generate test data for your test suite
curl -X POST http://localhost:3000/api/generate \
-d '{"message_type": "MT103", "scenario": "standard"}' \
> test_fixtures/mt103_sample.txt
SWIFT Certification
Generate valid messages for certification testing:
# Generate SR2025 compliant messages
curl -X POST http://localhost:3000/api/generate \
-d '{"message_type": "pacs.008", "scenario": "sr2025_standard"}'
Demo and Training
Create realistic examples for demonstrations:
# Generate various message types
for type in MT103 MT202 MT940; do
curl -X POST http://localhost:3000/api/generate \
-d "{\"message_type\": \"$type\", \"scenario\": \"standard\"}" \
> "samples/${type}.txt"
done
Transformation Testing
Generate source messages and verify transformation:
# Generate MT103
MT103=$(curl -s -X POST http://localhost:3000/api/generate \
-d '{"message_type": "MT103", "scenario": "standard"}' | jq -r .message)
# Transform to pacs.008
curl -X POST http://localhost:3000/api/transform \
-d "{\"message\": \"$MT103\"}"
Interactive Playground
Generate messages using the interactive playground:
Powered by Datafake
Sample generation uses Datafake, an open-source test data generation library. Datafake provides:
- Faker.js compatible API
- Deterministic output with seeds
- Financial domain generators (BIC, IBAN, amounts)
- Locale-aware data generation
Message Validation: SWIFT MT and ISO 20022
Validate SWIFT MT and ISO 20022 messages against schemas and business rules with the open source Reframe validation engine.
Overview
Reframe’s open source rules engine validates messages at multiple levels:
- Format Validation: Message structure and syntax
- Schema Validation: Field formats and required elements
- Business Validation: Package-specific business rules
- Custom Rules: User-defined validation rules via JSONLogic
API Usage
Basic Validation
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message": "{1:F01BNPAFRPPXXX...}",
"business_validation": true
}'
Response (Valid Message)
{
"status": "valid",
"message_type": "MT103",
"format": "swift_mt",
"validation": {
"format": "passed",
"schema": "passed",
"business": "passed"
},
"timing_ms": 0.5
}
Response (Invalid Message)
{
"status": "invalid",
"message_type": "MT103",
"format": "swift_mt",
"validation": {
"format": "passed",
"schema": "failed",
"business": "skipped"
},
"errors": [
{
"code": "FIELD_REQUIRED",
"field": "32A",
"message": "Tag 32A (Value Date/Currency/Amount) is required"
},
{
"code": "INVALID_FORMAT",
"field": "50K",
"message": "Account number must start with /"
}
]
}
Validation Options
| Option | Default | Description |
|---|---|---|
business_validation | false | Enable CBPR+ business rules |
canonical_json | false | Return parsed message as JSON |
fail_fast | false | Stop on first error |
Full Options Example
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message": "...",
"business_validation": true,
"canonical_json": true,
"fail_fast": false
}'
Format Detection
Reframe automatically detects the message format:
| Pattern | Detected Format |
|---|---|
Starts with {1: | SWIFT MT |
Contains xmlns="urn:iso:std:iso:20022 | ISO 20022 XML |
| XML with BAH | ISO 20022 with header |
SWIFT MT Validation
Block Structure
- Block 1: Basic header format
- Block 2: Application header format
- Block 3: User header (optional)
- Block 4: Text block with tags
- Block 5: Trailer (optional)
Tag Validation
| Check | Description |
|---|---|
| Tag presence | Required tags present |
| Tag format | Correct format per tag |
| Tag sequence | Tags in valid order |
| Tag length | Within max length |
Example Errors
{
"errors": [
{
"code": "BLOCK_STRUCTURE",
"message": "Block 1 is malformed"
},
{
"code": "MISSING_TAG",
"field": "32A",
"message": "Required tag 32A is missing"
},
{
"code": "INVALID_BIC",
"field": "52A",
"message": "Invalid BIC format in tag 52A"
}
]
}
ISO 20022 Validation
XML Schema Validation
- Well-formed XML
- Valid against XSD schema
- Correct namespace declarations
- Required elements present
Business Application Header
- Valid sender/receiver BIC
- Message definition identifier matches document
- Creation date/time format
Document Validation
| Check | Description |
|---|---|
| Required elements | All mandatory fields present |
| Data types | Correct format (dates, amounts, codes) |
| Enumerations | Valid code values |
| Constraints | Cross-field validations |
Example Errors
{
"errors": [
{
"code": "SCHEMA_VIOLATION",
"path": "/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt",
"message": "Currency attribute is required"
},
{
"code": "INVALID_DATE",
"path": "/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmDt",
"message": "Date must be in YYYY-MM-DD format"
}
]
}
Business Validation
When business_validation: true, package-specific rules are applied.
CBPR+ Package Rules
Party Identification
- Debtor/Creditor name required
- Valid account formats
- BIC format validation
Amount Rules
- Positive amounts only
- Currency code validation
- Settlement date validation
Agent Chain
- Valid BIC codes
- Required agent information
- Consistent agent chain
UETR Validation
- UUID format check
- Uniqueness (optional with persistence)
Canonical JSON Output
With canonical_json: true, the parsed message structure is returned:
SWIFT MT Canonical
{
"canonical": {
"basic_header": {
"app_id": "F",
"service_id": "01",
"lt_address": "BNPAFRPPXXX"
},
"application_header": {
"message_type": "103",
"receiver_address": "DEUTDEFFXXX"
},
"fields": {
"20": {"transaction_reference": "REF123456"},
"32A": {
"date": "250115",
"currency": "USD",
"amount": "50000,00"
}
}
}
}
ISO 20022 Canonical
{
"canonical": {
"app_header": {
"from": "BNPAFRPPXXX",
"to": "DEUTDEFFXXX",
"msg_def_id": "pacs.008.001.12"
},
"document": {
"grp_hdr": {
"msg_id": "MSG123",
"cre_dt_tm": "2025-01-15T10:30:00Z"
},
"cdt_trf_tx_inf": {
"pmt_id": {
"instr_id": "INSTR123",
"uetr": "174d2c70-..."
}
}
}
}
}
Error Codes
| Code | Description |
|---|---|
PARSE_ERROR | Cannot parse message |
BLOCK_STRUCTURE | Invalid MT block structure |
MISSING_TAG | Required tag missing |
INVALID_FORMAT | Field format error |
INVALID_BIC | Invalid BIC code |
INVALID_IBAN | Invalid IBAN |
INVALID_AMOUNT | Amount format error |
INVALID_DATE | Date format error |
SCHEMA_VIOLATION | XML schema error |
BUSINESS_RULE | Business rule violation |
Interactive Playground
Validate messages using the interactive playground:
Related Pages
- Validate API Reference - Complete API documentation
- Message Types Reference - Supported SWIFT MT and ISO 20022 types
- Error Codes Reference - Validation error codes
- Sample Generation - Generate test messages
- Interactive Playground - Try validation online
- FAQ - Common questions about Reframe
Hot Reload: Update Rules Without Restart
Update SWIFT MT and ISO 20022 transformation rules in production without downtime or service interruption.
Overview
Hot reloading allows you to:
- Update rules in production without downtime
- Test new mappings without restart
- Roll back changes quickly
Triggering a Reload
curl -X POST http://localhost:3000/admin/reload-workflows
Success Response:
{
"status": "success",
"message": "Workflows reloaded successfully",
"package": {
"id": "swift-cbpr-mt-mx",
"version": "2.1.2",
"workflows_loaded": 594
},
"timing_ms": 125
}
Error Response:
{
"status": "error",
"error": {
"code": "COMPILATION_ERROR",
"details": "Invalid JSONLogic in MT103/document-mapping.json"
}
}
Behavior
| Phase | Behavior |
|---|---|
| During reload | Existing requests continue; new requests may briefly queue |
| After reload | All new requests use updated rules |
| On error | Current rules remain active; error returned |
Development Workflow
Mount your package directory and iterate without restarts:
# docker-compose.yml
services:
reframe:
image: plasmatic/reframe:latest
volumes:
- ./my-package:/packages/custom
# Edit → Reload → Test cycle
vim my-package/transform/outgoing/MT103/document-mapping.json
curl -X POST http://localhost:3000/admin/reload-workflows
curl -X POST http://localhost:3000/api/transform -d '...'
CI/CD Integration
# GitHub Actions example
deploy-rules:
steps:
- run: scp -r rules/* server:/packages/swift-cbpr/
- run: curl -X POST https://api.example.com/admin/reload-workflows
- run: curl https://api.example.com/health
Best Practices
- Pre-validate: Test on staging before production reload
- Keep backups:
cp -r /packages/swift-cbpr /packages/swift-cbpr.backup - Version packages: Increment version in
reframe-package.jsonon changes - Monitor health: Check
/healthendpoint after reload
Monitoring
The health endpoint shows package info:
{
"status": "healthy",
"package": {
"id": "swift-cbpr-mt-mx",
"version": "2.1.2",
"loaded_at": "2025-01-15T10:30:00Z"
}
}
Related Pages
- Admin API Reference - Complete admin API documentation
- Packages and Rules - How transformation rules are organized
- Configuration Reference - Environment variables and settings
- Monitoring - Health checks and observability
Custom Fields
Define package-specific computed fields for analytics and monitoring.
Overview
Custom fields allow you to extract and compute values from transformed messages for:
- Analytics: Track transformation patterns
- Filtering: Query messages by business attributes
- Monitoring: Build dashboards and alerts
- Compliance: Extract regulatory reporting data
How It Works
Custom fields are defined in api_config.json within your transformation package:
{
"custom_fields": [
{
"name": "sender_country",
"type": "string",
"storage": "precompute",
"logic": {
"substr": [
{"var": "context.data.sender_bic"},
4,
2
]
}
}
]
}
The Reframe engine evaluates these JSONLogic expressions after each transformation and stores the results.
Field Definition
Structure
{
"name": "field_name",
"type": "string | number | boolean",
"storage": "precompute | runtime | hybrid",
"logic": { /* JSONLogic expression */ },
"description": "Optional field description"
}
Properties
| Property | Required | Description |
|---|---|---|
name | Yes | Unique field identifier |
type | Yes | Data type: string, number, boolean |
storage | Yes | When to compute the field |
logic | Yes | JSONLogic expression |
description | No | Human-readable description |
Storage Strategies
| Strategy | Computed | Stored | Best For |
|---|---|---|---|
precompute | At transformation time | Yes | Filtering, frequent queries |
runtime | At query time | No | Time-dependent values |
hybrid | Both | Yes | Updateable computations |
Example Custom Fields
Basic Extraction
Extract sender country from BIC:
{
"name": "sender_country",
"type": "string",
"storage": "precompute",
"logic": {
"substr": [{"var": "context.data.sender_bic"}, 4, 2]
}
}
Amount Banding
Categorize transactions by value:
{
"name": "amount_band",
"type": "string",
"storage": "precompute",
"logic": {
"if": [
{">": [{"var": "context.data.amount"}, 1000000]},
"HIGH",
{"if": [
{">": [{"var": "context.data.amount"}, 100000]},
"MEDIUM",
"LOW"
]}
]
}
}
Risk Scoring
Compute a risk score based on multiple factors:
{
"name": "risk_score",
"type": "number",
"storage": "precompute",
"logic": {
"+": [
{"if": [{">": [{"var": "context.data.amount"}, 500000]}, 30, 0]},
{"if": [{"in": [{"var": "context.data.receiver_country"}, ["HR", "RS", "BY"]]}, 40, 0]},
{"if": [{"!": {"var": "context.data.remittance_info"}}, 20, 0]},
10
]
}
}
Cross-Border Detection
Determine if payment is cross-border:
{
"name": "is_cross_border",
"type": "boolean",
"storage": "precompute",
"logic": {
"!=": [
{"substr": [{"var": "context.data.sender_bic"}, 4, 2]},
{"substr": [{"var": "context.data.receiver_bic"}, 4, 2]}
]
}
}
Processing Priority
Assign priority based on business rules:
{
"name": "processing_priority",
"type": "string",
"storage": "precompute",
"logic": {
"if": [
{"==": [{"var": "context.data.service_level"}, "G001"]},
"CRITICAL",
{"if": [
{"or": [
{">": [{"var": "context.data.amount"}, 1000000]},
{"==": [{"var": "context.data.service_level"}, "G002"]}
]},
"HIGH",
"NORMAL"
]}
]
}
}
Complete Configuration Example
// api_config.json
{
"custom_fields": [
{
"name": "sender_name",
"type": "string",
"storage": "precompute",
"logic": {"var": "context.data.debtor_name"}
},
{
"name": "receiver_name",
"type": "string",
"storage": "precompute",
"logic": {"var": "context.data.creditor_name"}
},
{
"name": "amount",
"type": "number",
"storage": "precompute",
"logic": {"var": "context.data.settlement_amount"}
},
{
"name": "currency",
"type": "string",
"storage": "precompute",
"logic": {"var": "context.data.settlement_currency"}
},
{
"name": "sender_country",
"type": "string",
"storage": "precompute",
"logic": {"substr": [{"var": "context.data.sender_bic"}, 4, 2]}
},
{
"name": "receiver_country",
"type": "string",
"storage": "precompute",
"logic": {"substr": [{"var": "context.data.receiver_bic"}, 4, 2]}
},
{
"name": "is_cross_border",
"type": "boolean",
"storage": "precompute",
"logic": {
"!=": [
{"substr": [{"var": "context.data.sender_bic"}, 4, 2]},
{"substr": [{"var": "context.data.receiver_bic"}, 4, 2]}
]
}
},
{
"name": "amount_band",
"type": "string",
"storage": "precompute",
"logic": {
"if": [
{">": [{"var": "context.data.settlement_amount"}, 1000000]},
"HIGH",
{"if": [
{">": [{"var": "context.data.settlement_amount"}, 100000]},
"MEDIUM",
"LOW"
]}
]
}
}
]
}
Querying Custom Fields
GraphQL API
Query messages using custom fields:
query {
messages(
filter: {
package_id: "swift-cbpr-mt-mx",
custom_field_filters: {
is_cross_border: true,
amount_band: "HIGH",
sender_country: "US"
}
},
limit: 100
) {
messages {
id
message_type
direction
custom_fields {
sender_name
receiver_name
amount
currency
is_cross_border
amount_band
}
created_at
}
total_count
}
}
Aggregations
query {
message_aggregations(
package_id: "swift-cbpr-mt-mx",
group_by: ["sender_country", "amount_band"],
date_range: {
start: "2025-01-01",
end: "2025-01-31"
}
) {
groups {
sender_country
amount_band
count
total_amount
}
}
}
Context Variables
Custom fields have access to transformation context:
| Variable | Description |
|---|---|
context.data.* | Parsed message data |
context.metadata.* | Message metadata |
context.temp_data.* | Intermediate values |
Available Data Fields
The available context.data fields depend on the message type. Common fields include:
sender_bic,receiver_bicdebtor_name,creditor_namesettlement_amount,settlement_currencyvalue_date,settlement_datemessage_type,directiontransaction_reference,uetrservice_level,charge_bearer
Best Practices
Naming Conventions
Use clear, consistent names:
sender_*,receiver_*for party datais_*for boolean flags*_datefor dates*_countfor counts
Performance
- Prefer
precomputefor frequently queried fields - Use
runtimefor time-dependent calculations - Keep expressions simple for better performance
Maintenance
- Document each field’s purpose
- Version your api_config.json
- Test field logic with sample data
API Reference
Complete reference for the Reframe open source rules engine REST API.
Base URL
Sandbox: https://reframeapi.goplasmatic.io
Local: http://localhost:3000
Authentication
The sandbox API requires no authentication (rate limited). For production deployments, configure authentication as needed.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST | /api/transform | Transform messages between formats |
POST | /api/validate | Validate MT or ISO 20022 messages |
POST | /api/generate | Generate sample messages |
POST | /admin/reload-workflows | Hot reload transformation rules |
GET | /health | Health check |
GET | /packages | List loaded packages |
GET | /swagger-ui | Interactive API documentation |
POST | /graphql | GraphQL endpoint |
Common Response Format
Success Response
{
"status": "success",
"message": "...",
"timing_ms": 1.2,
"metadata": {
"package": "swift-cbpr-mt-mx",
"version": "2.1.2"
}
}
Error Response
{
"status": "error",
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {}
}
}
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
PARSE_ERROR | 400 | Cannot parse input message |
VALIDATION_ERROR | 400 | Message validation failed |
TRANSFORMATION_ERROR | 400 | Transformation failed |
UNSUPPORTED_TYPE | 400 | Message type not supported |
INTERNAL_ERROR | 500 | Internal server error |
Request Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | application/json |
Accept | No | application/json (default) |
Rate Limiting
Sandbox API:
- 100 requests per minute per IP
- 1000 requests per hour per IP
Rate limit headers in response:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800
Quick Examples
Transform a Message
curl -X POST https://reframeapi.goplasmatic.io/api/transform \
-H "Content-Type: application/json" \
-d '{"message": "{1:F01BNPAFRPPXXX...}"}'
Validate a Message
curl -X POST https://reframeapi.goplasmatic.io/api/validate \
-H "Content-Type: application/json" \
-d '{"message": "...", "business_validation": true}'
Generate a Sample
curl -X POST https://reframeapi.goplasmatic.io/api/generate \
-H "Content-Type: application/json" \
-d '{"message_type": "MT103", "scenario": "standard"}'
Check Health
curl https://reframeapi.goplasmatic.io/health
OpenAPI / Swagger
Interactive API documentation is available at:
- Sandbox:
https://reframeapi.goplasmatic.io/swagger-ui - Local:
http://localhost:3000/swagger-ui
Transform API
Transform messages between SWIFT MT and ISO 20022 formats.
Endpoint
POST /api/transform
Request
Headers
| Header | Value |
|---|---|
Content-Type | application/json |
Body
{
"message": "string (required)",
"validation": "boolean (optional, default: false)",
"debug": "boolean (optional, default: false)",
"metadata": "object (optional)"
}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
message | string | Yes | The message to transform (MT or ISO 20022) |
validation | boolean | No | Validate before and after transformation |
debug | boolean | No | Include debug information in response |
metadata | object | No | User-provided metadata to include in response |
Response
Success (200 OK)
{
"status": "success",
"direction": "outgoing",
"source_type": "MT103",
"target_type": "pacs.008.001.12",
"message": "<transformed message>",
"timing_ms": 1.2,
"metadata": {
"package": "swift-cbpr-mt-mx",
"version": "2.1.2"
}
}
With Debug (200 OK)
{
"status": "success",
"direction": "outgoing",
"source_type": "MT103",
"target_type": "pacs.008.001.12",
"message": "<transformed message>",
"timing_ms": 1.2,
"debug": {
"workflows_executed": [
{"id": "parse-mt", "priority": 1, "timing_ms": 0.2},
{"id": "mt103-bah-mapping", "priority": 3, "timing_ms": 0.3},
{"id": "mt103-document-mapping", "priority": 5, "timing_ms": 0.5},
{"id": "combine-xml", "priority": 10, "timing_ms": 0.2}
],
"parsed_input": {...},
"intermediate_values": {...}
}
}
Validation Error (400 Bad Request)
{
"status": "error",
"error": {
"code": "VALIDATION_ERROR",
"message": "Input validation failed",
"errors": [
{
"code": "MISSING_TAG",
"field": "32A",
"message": "Tag 32A is required"
}
]
}
}
Transformation Error (400 Bad Request)
{
"status": "error",
"error": {
"code": "TRANSFORMATION_ERROR",
"message": "Failed to transform message",
"details": {
"workflow": "mt103-document-mapping",
"task": "map-amount",
"reason": "Missing source field"
}
}
}
Auto-Detection
The API automatically detects:
| Input Pattern | Detection |
|---|---|
Starts with {1: | SWIFT MT format |
| XML with ISO 20022 namespace | ISO 20022 format |
| Block 2 message type | Specific MT type (103, 202, etc.) |
| MsgDefIdr element | Specific ISO 20022 type |
Examples
MT103 to pacs.008
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{3:{121:f47ac10b-58cc-4372-a567-0e02b2c3d479}}{4:\n:20:REF123456\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/12345678\nACME CORP\n:59:/98765432\nGLOBAL LTD\n:71A:SHA\n-}"
}'
pacs.008 to MT103
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "<?xml version=\"1.0\"?><Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12\">...</Document>"
}'
With Validation
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "{1:F01BNPAFRPPXXX...}",
"validation": true
}'
With Debug
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "{1:F01BNPAFRPPXXX...}",
"debug": true
}'
With Metadata
curl -X POST http://localhost:3000/api/transform \
-H "Content-Type: application/json" \
-d '{
"message": "{1:F01BNPAFRPPXXX...}",
"metadata": {
"request_id": "req-12345",
"source_system": "payment-gateway"
}
}'
Supported Transformations
For the complete list of supported message transformations, see Message Catalog →
Validate API
Validate SWIFT MT and ISO 20022 messages.
Endpoint
POST /api/validate
Request
Headers
| Header | Value |
|---|---|
Content-Type | application/json |
Body
{
"message": "string (required)",
"business_validation": "boolean (optional, default: false)",
"canonical_json": "boolean (optional, default: false)",
"fail_fast": "boolean (optional, default: false)"
}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
message | string | Yes | The message to validate |
business_validation | boolean | No | Apply CBPR+ business rules |
canonical_json | boolean | No | Return parsed message structure |
fail_fast | boolean | No | Stop on first validation error |
Response
Valid Message (200 OK)
{
"status": "valid",
"message_type": "MT103",
"format": "swift_mt",
"validation": {
"format": "passed",
"schema": "passed",
"business": "passed"
},
"timing_ms": 0.5
}
With Canonical JSON (200 OK)
{
"status": "valid",
"message_type": "MT103",
"format": "swift_mt",
"validation": {
"format": "passed",
"schema": "passed"
},
"canonical": {
"basic_header": {
"app_id": "F",
"service_id": "01",
"lt_address": "BNPAFRPPXXX"
},
"application_header": {
"io_identifier": "I",
"message_type": "103",
"receiver_address": "DEUTDEFFXXX"
},
"user_header": {
"121": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
},
"fields": {
"20": {"transaction_reference": "REF123456"},
"23B": {"bank_operation_code": "CRED"},
"32A": {
"date": "250115",
"currency": "USD",
"amount": "50000,00"
},
"50K": {
"account": "12345678",
"name": "ACME CORP"
},
"59": {
"account": "98765432",
"name": "GLOBAL LTD"
},
"71A": {"details_of_charges": "SHA"}
}
}
}
Invalid Message (200 OK with errors)
{
"status": "invalid",
"message_type": "MT103",
"format": "swift_mt",
"validation": {
"format": "passed",
"schema": "failed",
"business": "skipped"
},
"errors": [
{
"code": "MISSING_TAG",
"field": "32A",
"message": "Tag 32A (Value Date/Currency/Amount) is required",
"severity": "error"
},
{
"code": "INVALID_FORMAT",
"field": "50K",
"message": "Account must start with /",
"severity": "error"
}
]
}
Parse Error (400 Bad Request)
{
"status": "error",
"error": {
"code": "PARSE_ERROR",
"message": "Cannot parse message",
"details": {
"position": 45,
"expected": "Block 4 start",
"found": "Invalid character"
}
}
}
Validation Levels
Format Validation
Basic structural checks:
SWIFT MT:
- Block delimiters
{1:,{2:, etc. - Field separators
- Block sequence
ISO 20022:
- Well-formed XML
- Valid namespaces
- Basic structure
Schema Validation
Message specification checks:
SWIFT MT:
- Required tags present
- Tag formats correct
- Field lengths within limits
- Valid code values
ISO 20022:
- XSD schema compliance
- Required elements present
- Data types correct
- Enumeration values valid
Business Validation
CBPR+ business rules (when enabled):
- BIC format (8 or 11 characters)
- IBAN checksum validation
- Amount positive and formatted
- Date formats (YYMMDD or YYYY-MM-DD)
- Service level codes (G001-G004)
- Charge bearer codes (SHAR, DEBT, CRED)
- UETR format (UUID v4)
Error Codes
| Code | Description |
|---|---|
PARSE_ERROR | Cannot parse message structure |
BLOCK_STRUCTURE | Invalid MT block structure |
MISSING_TAG | Required tag missing |
INVALID_FORMAT | Field format incorrect |
INVALID_LENGTH | Field length exceeded |
INVALID_BIC | Invalid BIC code |
INVALID_IBAN | Invalid IBAN |
INVALID_AMOUNT | Amount format error |
INVALID_DATE | Date format error |
INVALID_CODE | Invalid code value |
SCHEMA_VIOLATION | XML schema error |
BUSINESS_RULE | Business rule violation |
Examples
Basic Validation
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{4:\n:20:REF123\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/1234\nSENDER\n:59:/5678\nRECEIVER\n:71A:SHA\n-}"
}'
With Business Validation
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message": "...",
"business_validation": true
}'
With Canonical JSON
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message": "...",
"canonical_json": true
}'
Validate ISO 20022
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message": "<?xml version=\"1.0\"?><Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12\">...</Document>",
"business_validation": true
}'
Generate API
Generate sample SWIFT MT and ISO 20022 messages.
Endpoint
POST /api/generate
Request
Headers
| Header | Value |
|---|---|
Content-Type | application/json |
Body
{
"message_type": "string (required)",
"scenario": "string (optional, default: 'standard')"
}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
message_type | string | Yes | Message type to generate (MT103, pacs.008, etc.) |
scenario | string | No | Scenario variant (standard, high_value, etc.) |
Response
Success (200 OK)
{
"status": "success",
"message_type": "MT103",
"scenario": "standard",
"message": "{1:F01BNPAFRPPXXX0000000000}...",
"metadata": {
"generated_at": "2025-01-15T10:30:00Z",
"package": "swift-cbpr-mt-mx",
"version": "2.1.2"
}
}
Unsupported Type (400 Bad Request)
{
"status": "error",
"error": {
"code": "UNSUPPORTED_TYPE",
"message": "Message type 'MT999' is not supported",
"supported_types": ["MT103", "MT202", "MT940", "pacs.008", "pacs.009", "..."]
}
}
Unknown Scenario (400 Bad Request)
{
"status": "error",
"error": {
"code": "UNKNOWN_SCENARIO",
"message": "Scenario 'custom' not found for MT103",
"available_scenarios": ["standard", "high_value", "remittance"]
}
}
Supported Message Types
SWIFT MT Messages
| Type | Description | Scenarios |
|---|---|---|
MT101 | Request for Transfer | standard |
MT103 | Single Customer Credit Transfer | standard, high_value, remittance |
MT103STP | Straight-Through Processing | standard |
MT200 | Financial Institution Transfer | standard |
MT202 | General FI Transfer | standard, cover |
MT202COV | Cover Payment | standard |
MT205 | FI Transfer (Third Party) | standard |
MT900 | Confirmation of Debit | standard |
MT910 | Confirmation of Credit | standard |
MT940 | Customer Statement | standard, multi_entry |
MT942 | Interim Transaction Report | standard |
ISO 20022 Messages
| Type | Description | Scenarios |
|---|---|---|
pacs.002 | Payment Status Report | accepted, rejected |
pacs.004 | Payment Return | standard |
pacs.008 | FI to FI Customer Credit Transfer | standard, high_value |
pacs.009 | FI to FI FI Credit Transfer | standard, cover |
camt.029 | Resolution of Investigation | standard |
camt.052 | Account Report | standard |
camt.053 | Bank Statement | standard |
camt.054 | Debit/Credit Notification | debit, credit |
camt.056 | Cancellation Request | standard |
Scenario Details
MT103 Scenarios
standard: Basic customer credit transfer
- Amount: $10,000 - $100,000
- Standard party information
- SHA charges
high_value: Large value transfer
- Amount: $500,000 - $5,000,000
- Full party details with addresses
- Complete agent chain
remittance: With remittance information
- Includes Tag 70 (remittance info)
- Invoice/PO references
- Regulatory reporting
pacs.008 Scenarios
standard: Basic ISO 20022 transfer
- SR2025 compliant structure
- UETR included
- Standard party identification
high_value: Enhanced party details
- LEI identifiers
- Structured addresses
- Full creditor reference
Examples
Generate MT103
curl -X POST http://localhost:3000/api/generate \
-H "Content-Type: application/json" \
-d '{
"message_type": "MT103",
"scenario": "standard"
}'
Generate pacs.008
curl -X POST http://localhost:3000/api/generate \
-H "Content-Type: application/json" \
-d '{
"message_type": "pacs.008",
"scenario": "standard"
}'
Generate High-Value MT103
curl -X POST http://localhost:3000/api/generate \
-H "Content-Type: application/json" \
-d '{
"message_type": "MT103",
"scenario": "high_value"
}'
Generate MT940 Statement
curl -X POST http://localhost:3000/api/generate \
-H "Content-Type: application/json" \
-d '{
"message_type": "MT940",
"scenario": "multi_entry"
}'
Sample Output
MT103 (standard)
{1:F01CITIUS33XXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:a1b2c3d4-e5f6-7890-abcd-ef1234567890}}
{4:
:20:TRF20250115001
:23B:CRED
:32A:250115USD75000,00
:50K:/US33445566778899
ACME INTERNATIONAL INC
1234 CORPORATE BLVD
NEW YORK NY 10001
:57A:COBADEFFXXX
:59:/DE89370400440532013000
MUNICH TRADING GMBH
LEOPOLDSTRASSE 100
80802 MUNICH
:70:/INV/2025-00123
:71A:SHA
-}
pacs.008 (standard)
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>MSG20250115001</MsgId>
<CreDtTm>2025-01-15T10:30:00Z</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<SttlmInf>
<SttlmMtd>INDA</SttlmMtd>
</SttlmInf>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<InstrId>INSTR20250115001</InstrId>
<EndToEndId>E2E20250115001</EndToEndId>
<UETR>a1b2c3d4-e5f6-7890-abcd-ef1234567890</UETR>
</PmtId>
<PmtTpInf>
<SvcLvl><Cd>G002</Cd></SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="EUR">45000.00</IntrBkSttlmAmt>
<IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
<ChrgBr>SHAR</ChrgBr>
<Dbtr>
<Nm>SENDER CORPORATION</Nm>
</Dbtr>
<DbtrAgt>
<FinInstnId>
<BICFI>BNPAFRPPXXX</BICFI>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BICFI>DEUTDEFFXXX</BICFI>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>RECEIVER GMBH</Nm>
</Cdtr>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
Admin API
Administrative endpoints for managing Reframe.
Reload Workflows
Hot reload transformation rules without restarting.
Endpoint
POST /admin/reload-workflows
Request
No request body required.
Response (Success)
{
"status": "success",
"message": "Workflows reloaded successfully",
"package": {
"id": "swift-cbpr-mt-mx",
"version": "2.1.2",
"workflows_loaded": 594
},
"timing_ms": 125
}
Response (Error)
{
"status": "error",
"message": "Failed to reload workflows",
"error": {
"code": "COMPILATION_ERROR",
"details": "Invalid JSONLogic in MT103/document-mapping.json at line 45"
}
}
Example
curl -X POST http://localhost:3000/admin/reload-workflows
Health Check
Check service health and engine status.
Endpoint
GET /health
Response (Healthy)
{
"status": "healthy",
"engines": {
"transform": "ready",
"generation": "ready",
"validation": "ready"
},
"package": {
"id": "swift-cbpr-mt-mx",
"version": "2.1.2",
"loaded_at": "2025-01-15T10:30:00Z"
},
"uptime_seconds": 86400
}
Response (Unhealthy)
{
"status": "unhealthy",
"engines": {
"transform": "error",
"generation": "ready",
"validation": "ready"
},
"error": "Transform engine failed to initialize"
}
Example
curl http://localhost:3000/health
List Packages
List loaded transformation packages.
Endpoint
GET /packages
Response
{
"packages": [
{
"id": "swift-cbpr-mt-mx",
"name": "SWIFT CBPR+ MT <-> MX Transformations",
"version": "2.1.2",
"engine_version": "3.1.4",
"loaded_at": "2025-01-15T10:30:00Z",
"workflows": {
"transform": 594,
"validate": 12,
"generate": 8
},
"scenarios": {
"outgoing": 23,
"incoming": 32
}
}
]
}
Example
curl http://localhost:3000/packages
OpenAPI Documentation
Interactive API documentation.
Endpoint
GET /swagger-ui
Opens the Swagger UI interface in a web browser.
Example
# Open in browser
open http://localhost:3000/swagger-ui
Configuration Endpoints
Get Current Configuration
GET /admin/config
Returns the current runtime configuration (excludes sensitive data).
{
"server": {
"host": "0.0.0.0",
"port": 3000,
"workers": 4
},
"logging": {
"level": "info",
"format": "compact"
},
"packages": [
{
"path": "/packages/swift-cbpr",
"enabled": true
}
]
}
Example
curl http://localhost:3000/admin/config
Metrics Endpoint
Prometheus-compatible metrics (if enabled).
Endpoint
GET /metrics
Response
# HELP reframe_requests_total Total number of requests
# TYPE reframe_requests_total counter
reframe_requests_total{endpoint="/api/transform",status="success"} 12345
reframe_requests_total{endpoint="/api/validate",status="success"} 8901
# HELP reframe_request_duration_seconds Request duration
# TYPE reframe_request_duration_seconds histogram
reframe_request_duration_seconds_bucket{endpoint="/api/transform",le="0.001"} 10234
reframe_request_duration_seconds_bucket{endpoint="/api/transform",le="0.01"} 12100
# HELP reframe_messages_transformed_total Total messages transformed
# TYPE reframe_messages_transformed_total counter
reframe_messages_transformed_total{direction="outgoing",type="MT103"} 5678
reframe_messages_transformed_total{direction="incoming",type="pacs.008"} 4321
Example
curl http://localhost:3000/metrics
Security Considerations
Admin Endpoints
Admin endpoints should be protected in production:
- Use a reverse proxy to restrict access
- Implement IP whitelisting
- Add authentication if needed
Example: nginx Protection
location /admin/ {
allow 10.0.0.0/8;
deny all;
proxy_pass http://reframe:3000;
}
Example: Authentication Header
# If authentication is configured
curl -H "Authorization: Bearer <token>" \
http://localhost:3000/admin/reload-workflows
GraphQL API
Query transformation history and analytics using GraphQL.
Endpoint
POST /graphql
Playground
Interactive GraphQL playground:
GET /graphql
Open in browser to explore the schema and run queries.
Schema Overview
Types
type Message {
id: ID!
message_type: String!
direction: String!
source_message: String!
target_message: String!
status: String!
package_id: String!
created_at: DateTime!
timing_ms: Float!
custom_fields: CustomFields
}
type CustomFields {
sender_name: String
receiver_name: String
amount: Float
currency: String
sender_country: String
receiver_country: String
is_cross_border: Boolean
amount_band: String
}
type MessageConnection {
messages: [Message!]!
total_count: Int!
has_next_page: Boolean!
}
type Aggregation {
group_key: String!
count: Int!
total_amount: Float
}
Queries
type Query {
# Get a single message by ID
message(id: ID!): Message
# Query messages with filtering
messages(
filter: MessageFilter
limit: Int = 100
offset: Int = 0
order_by: OrderBy
): MessageConnection!
# Aggregate messages
message_aggregations(
package_id: String!
group_by: [String!]!
filter: MessageFilter
): [Aggregation!]!
}
Filters
input MessageFilter {
package_id: String
message_type: String
direction: String
status: String
date_range: DateRange
custom_field_filters: CustomFieldFilters
}
input DateRange {
start: DateTime!
end: DateTime!
}
input CustomFieldFilters {
sender_country: String
receiver_country: String
is_cross_border: Boolean
amount_band: String
amount_min: Float
amount_max: Float
}
input OrderBy {
field: String!
direction: SortDirection!
}
enum SortDirection {
ASC
DESC
}
Query Examples
Get Recent Messages
query {
messages(
filter: {
package_id: "swift-cbpr-mt-mx"
},
limit: 10,
order_by: { field: "created_at", direction: DESC }
) {
messages {
id
message_type
direction
status
created_at
timing_ms
}
total_count
}
}
Filter by Custom Fields
query {
messages(
filter: {
package_id: "swift-cbpr-mt-mx",
custom_field_filters: {
is_cross_border: true,
amount_band: "HIGH",
sender_country: "US"
}
},
limit: 100
) {
messages {
id
message_type
custom_fields {
sender_name
receiver_name
amount
currency
sender_country
receiver_country
}
}
total_count
}
}
Filter by Date Range
query {
messages(
filter: {
package_id: "swift-cbpr-mt-mx",
date_range: {
start: "2025-01-01T00:00:00Z",
end: "2025-01-31T23:59:59Z"
}
}
) {
messages {
id
message_type
created_at
}
total_count
}
}
Get Message by ID
query {
message(id: "msg-12345") {
id
message_type
direction
source_message
target_message
status
created_at
timing_ms
custom_fields {
sender_name
receiver_name
amount
currency
}
}
}
Aggregate by Country
query {
message_aggregations(
package_id: "swift-cbpr-mt-mx",
group_by: ["sender_country"],
filter: {
date_range: {
start: "2025-01-01T00:00:00Z",
end: "2025-01-31T23:59:59Z"
}
}
) {
group_key
count
total_amount
}
}
Aggregate by Multiple Dimensions
query {
message_aggregations(
package_id: "swift-cbpr-mt-mx",
group_by: ["sender_country", "amount_band"],
filter: {
custom_field_filters: {
is_cross_border: true
}
}
) {
group_key
count
total_amount
}
}
Using curl
Basic Query
curl -X POST http://localhost:3000/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "query { messages(limit: 10) { messages { id message_type } } }"
}'
Query with Variables
curl -X POST http://localhost:3000/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "query GetMessages($limit: Int!) { messages(limit: $limit) { messages { id } } }",
"variables": {"limit": 50}
}'
Requirements
GraphQL queries require:
- MongoDB persistence enabled in configuration
- Message storage enabled for transformations
Configuration
{
"database": {
"mongodb_uri": "mongodb://localhost:27017",
"database_name": "reframe",
"store_messages": true
}
}
Custom Fields
Custom fields are defined in the package’s api_config.json and computed during transformation. Common fields include:
| Field | Type | Description |
|---|---|---|
sender_name | string | Debtor name |
receiver_name | string | Creditor name |
amount | number | Settlement amount |
currency | string | Currency code |
sender_country | string | Sender country (from BIC) |
receiver_country | string | Receiver country (from BIC) |
is_cross_border | boolean | Cross-border indicator |
amount_band | string | HIGH/MEDIUM/LOW |
Kubernetes Deployment
Deploy Reframe on Kubernetes for production workloads.
Basic Deployment
Deployment
# reframe-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: reframe
labels:
app: reframe
spec:
replicas: 3
selector:
matchLabels:
app: reframe
template:
metadata:
labels:
app: reframe
spec:
containers:
- name: reframe
image: plasmatic/reframe:3.1.8
ports:
- containerPort: 3000
env:
- name: RUST_LOG
value: "info"
- name: TOKIO_WORKER_THREADS
value: "4"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "1000m"
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
Service
# reframe-service.yaml
apiVersion: v1
kind: Service
metadata:
name: reframe
spec:
selector:
app: reframe
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP
Ingress
# reframe-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: reframe
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: reframe-tls
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: reframe
port:
number: 80
Apply Resources
kubectl apply -f reframe-deployment.yaml
kubectl apply -f reframe-service.yaml
kubectl apply -f reframe-ingress.yaml
ConfigMap
Configuration File
# reframe-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: reframe-config
data:
reframe.config.json: |
{
"server": {
"host": "0.0.0.0",
"port": 3000
},
"logging": {
"level": "info",
"format": "json"
}
}
Mount ConfigMap
spec:
containers:
- name: reframe
volumeMounts:
- name: config
mountPath: /app/reframe.config.json
subPath: reframe.config.json
volumes:
- name: config
configMap:
name: reframe-config
Custom Package
Using PersistentVolume
# reframe-pv.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: reframe-packages
spec:
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 1Gi
spec:
containers:
- name: reframe
volumeMounts:
- name: packages
mountPath: /packages/custom
env:
- name: REFRAME_PACKAGE_PATH
value: "/packages"
volumes:
- name: packages
persistentVolumeClaim:
claimName: reframe-packages
Horizontal Pod Autoscaler
# reframe-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: reframe
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: reframe
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Pod Disruption Budget
# reframe-pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: reframe
spec:
minAvailable: 1
selector:
matchLabels:
app: reframe
Network Policy
# reframe-network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: reframe
spec:
podSelector:
matchLabels:
app: reframe
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 3000
egress:
- to:
- namespaceSelector: {}
ports:
- protocol: TCP
port: 443
Helm Chart
values.yaml
replicaCount: 3
image:
repository: plasmatic/reframe
tag: "3.1.8"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: nginx
hosts:
- host: api.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: reframe-tls
hosts:
- api.example.com
resources:
limits:
cpu: 1000m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
env:
RUST_LOG: info
TOKIO_WORKER_THREADS: "4"
Monitoring
ServiceMonitor (Prometheus)
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: reframe
spec:
selector:
matchLabels:
app: reframe
endpoints:
- port: http
path: /metrics
interval: 30s
Operations
Check Status
kubectl get pods -l app=reframe
kubectl get svc reframe
kubectl get ingress reframe
View Logs
kubectl logs -l app=reframe -f
Scale
kubectl scale deployment reframe --replicas=5
Rolling Update
kubectl set image deployment/reframe reframe=plasmatic/reframe:3.2.0
kubectl rollout status deployment/reframe
Rollback
kubectl rollout undo deployment/reframe
Configuration Reference
Complete configuration options for Reframe.
Configuration Sources
Configuration is loaded in priority order:
- Environment variables (highest)
- Configuration file (
reframe.config.json) - Built-in defaults (lowest)
Environment Variables
| Variable | Default | Description |
|---|---|---|
REFRAME_HOST | 0.0.0.0 | Server bind address |
REFRAME_PORT | 3000 | Server port |
REFRAME_PACKAGE_PATH | /packages | Package directory |
TOKIO_WORKER_THREADS | CPU cores | Async worker threads |
RUST_LOG | info | Log level |
RUST_LOG_FORMAT | compact | Log format (compact/json/pretty) |
MONGODB_URI | - | MongoDB connection string |
MONGODB_DATABASE | reframe | Database name |
Configuration File
Create reframe.config.json in the working directory:
{
"server": {
"host": "0.0.0.0",
"port": 3000,
"workers": 4
},
"logging": {
"level": "info",
"format": "compact",
"file": null
},
"packages": [
{
"path": "/packages/swift-cbpr",
"enabled": true
}
],
"database": {
"mongodb_uri": "mongodb://localhost:27017",
"database_name": "reframe",
"store_messages": false
},
"api_docs": {
"enabled": true,
"title": "Reframe API",
"version": "3.1.8"
}
}
Section Details
Server
{
"server": {
"host": "0.0.0.0",
"port": 3000,
"workers": 4
}
}
| Option | Type | Default | Description |
|---|---|---|---|
host | string | 0.0.0.0 | Bind address |
port | number | 3000 | Listen port |
workers | number | CPU cores | Tokio worker threads |
Logging
{
"logging": {
"level": "info",
"format": "compact",
"file": {
"path": "/var/log/reframe/reframe.log",
"rotation": "daily",
"max_files": 7
}
}
}
| Option | Type | Default | Description |
|---|---|---|---|
level | string | info | Log level (trace/debug/info/warn/error) |
format | string | compact | Output format (compact/json/pretty) |
file.path | string | null | Log file path |
file.rotation | string | daily | Rotation (daily/hourly/never) |
file.max_files | number | 7 | Files to keep |
Packages
{
"packages": [
{
"path": "/packages/swift-cbpr",
"enabled": true
},
{
"path": "/packages/custom",
"enabled": false
}
]
}
| Option | Type | Description |
|---|---|---|
path | string | Path to package directory |
enabled | boolean | Whether to load this package |
Database
{
"database": {
"mongodb_uri": "mongodb://localhost:27017",
"database_name": "reframe",
"store_messages": true,
"ttl_days": 90
}
}
| Option | Type | Default | Description |
|---|---|---|---|
mongodb_uri | string | - | MongoDB connection URI |
database_name | string | reframe | Database name |
store_messages | boolean | false | Store transformed messages |
ttl_days | number | 90 | Message retention days |
API Documentation
{
"api_docs": {
"enabled": true,
"title": "Reframe API",
"version": "3.1.8",
"description": "ISO 20022 Transformation Engine",
"contact": {
"name": "Support",
"email": "support@example.com"
}
}
}
Complete Example
{
"server": {
"host": "0.0.0.0",
"port": 3000,
"workers": 8
},
"logging": {
"level": "info",
"format": "json",
"file": {
"path": "/var/log/reframe/reframe.log",
"rotation": "daily",
"max_files": 30
}
},
"packages": [
{
"path": "/packages/swift-cbpr",
"enabled": true
}
],
"database": {
"mongodb_uri": "mongodb://mongo:27017",
"database_name": "reframe_prod",
"store_messages": true,
"ttl_days": 365
},
"api_docs": {
"enabled": true,
"title": "Reframe Production API",
"version": "3.1.8"
}
}
Docker Configuration
Environment Variables
docker run \
-e REFRAME_PORT=8080 \
-e RUST_LOG=debug \
-e TOKIO_WORKER_THREADS=8 \
plasmatic/reframe:latest
Configuration File Mount
docker run \
-v /path/to/reframe.config.json:/app/reframe.config.json \
plasmatic/reframe:latest
Kubernetes Configuration
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: reframe-config
data:
reframe.config.json: |
{
"server": {
"port": 3000
},
"logging": {
"level": "info",
"format": "json"
}
}
Secret (for sensitive values)
apiVersion: v1
kind: Secret
metadata:
name: reframe-secrets
type: Opaque
stringData:
MONGODB_URI: "mongodb://user:pass@host:27017"
Validation
Reframe validates configuration on startup:
2025-01-15T10:30:00Z INFO reframe: Loading configuration
2025-01-15T10:30:00Z INFO reframe: Server: 0.0.0.0:3000
2025-01-15T10:30:00Z INFO reframe: Workers: 8
2025-01-15T10:30:00Z INFO reframe: Log level: info
2025-01-15T10:30:00Z INFO reframe: Package: /packages/swift-cbpr (enabled)
Invalid configuration causes startup failure with clear error messages.
Monitoring
Monitor Reframe in production environments.
Health Checks
HTTP Health Endpoint
curl http://localhost:3000/health
Response:
{
"status": "healthy",
"engines": {
"transform": "ready",
"generation": "ready",
"validation": "ready"
},
"package": {
"id": "swift-cbpr-mt-mx",
"version": "2.1.2",
"loaded_at": "2025-01-15T10:30:00Z"
},
"uptime_seconds": 86400
}
Docker Health Check
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
Kubernetes Probes
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
Metrics
Prometheus Endpoint
curl http://localhost:3000/metrics
Available Metrics
# Request metrics
reframe_requests_total{endpoint,status}
reframe_request_duration_seconds{endpoint,le}
# Transformation metrics
reframe_transformations_total{direction,type,status}
reframe_transformation_duration_seconds{direction,type,le}
# Validation metrics
reframe_validations_total{format,status}
# Generation metrics
reframe_generations_total{type}
# System metrics
reframe_uptime_seconds
reframe_package_workflows_total
Prometheus Configuration
# prometheus.yml
scrape_configs:
- job_name: 'reframe'
static_configs:
- targets: ['reframe:3000']
metrics_path: /metrics
scrape_interval: 30s
Grafana Dashboard
Key panels to include:
- Request Rate:
rate(reframe_requests_total[5m]) - Error Rate:
rate(reframe_requests_total{status="error"}[5m]) - Latency P99:
histogram_quantile(0.99, rate(reframe_request_duration_seconds_bucket[5m])) - Transformations by Type:
sum by (type) (rate(reframe_transformations_total[5m]))
Logging
Log Levels
| Level | Description |
|---|---|
error | Errors only |
warn | Warnings and errors |
info | General info (recommended for production) |
debug | Debug information |
trace | Detailed tracing |
Log Formats
compact (default):
2025-01-15T10:30:00Z INFO reframe::api: Transform request direction=outgoing type=MT103
json (for log aggregation):
{"timestamp":"2025-01-15T10:30:00Z","level":"INFO","target":"reframe::api","message":"Transform request","direction":"outgoing","type":"MT103"}
pretty (for development):
2025-01-15T10:30:00.123Z INFO reframe::api: Transform request
direction: outgoing
type: MT103
Log Aggregation
Fluentd
<source>
@type tail
path /var/log/reframe/*.log
pos_file /var/log/fluentd/reframe.pos
tag reframe
<parse>
@type json
</parse>
</source>
Loki
scrape_configs:
- job_name: reframe
static_configs:
- targets:
- localhost
labels:
job: reframe
__path__: /var/log/reframe/*.log
Alerting
Key Alerts
High Error Rate
- alert: ReframeHighErrorRate
expr: rate(reframe_requests_total{status="error"}[5m]) > 0.1
for: 5m
labels:
severity: critical
annotations:
summary: High error rate in Reframe
High Latency
- alert: ReframeHighLatency
expr: histogram_quantile(0.99, rate(reframe_request_duration_seconds_bucket[5m])) > 1
for: 5m
labels:
severity: warning
annotations:
summary: High latency in Reframe
Service Down
- alert: ReframeDown
expr: up{job="reframe"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: Reframe service is down
Package Reload Failed
- alert: ReframePackageError
expr: reframe_package_load_errors_total > 0
for: 1m
labels:
severity: warning
annotations:
summary: Package reload failed
Tracing
OpenTelemetry (if enabled)
{
"tracing": {
"enabled": true,
"exporter": "otlp",
"endpoint": "http://jaeger:4317",
"service_name": "reframe"
}
}
Trace Context
Reframe propagates trace context through headers:
traceparenttracestate
Dashboard Example
Key Metrics to Display
-
Overview
- Requests per second
- Error rate percentage
- Average latency
-
Transformations
- By direction (outgoing/incoming)
- By message type
- Success/failure rate
-
System
- CPU usage
- Memory usage
- Uptime
-
Package
- Loaded workflows
- Last reload time
- Reload errors
Best Practices
- Set appropriate log level - Use
infofor production - Use JSON logging - Easier to parse and aggregate
- Configure alerts - Catch issues before users notice
- Monitor latency - P99 is more important than average
- Track by message type - Identify problematic transformations
- Set retention policies - Don’t fill up storage
Technology Overview
The open-source foundation powering Reframe.
Architecture
Reframe is built on a modular architecture with specialized libraries:
┌─────────────────────────────────────────────────────────────┐
│ Reframe Engine │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Dataflow │ │ Datalogic │ │ Datafake │ │
│ │ Workflows │ │ Rules │ │ Data Generation │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ swift-mt-message │ mx-message │ quick-xml │ │
│ │ MT Parsing │ MX Parsing │ XML Processing │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Core Libraries
| Library | Purpose | Role in Reframe |
|---|---|---|
| Dataflow | Workflow orchestration | Executes transformation pipelines |
| Datalogic | JSONLogic evaluation | Processes business rules and mappings |
| Datafake | Test data generation | Generates sample messages |
Why These Libraries?
Separation of Concerns
Each library handles a specific responsibility:
- Dataflow: Orchestrates when and how workflows execute
- Datalogic: Evaluates what transformations to apply
- Datafake: Generates realistic test data
Performance
All libraries are:
- Written in Rust for memory safety and speed
- Pre-compiled at startup (zero runtime parsing)
- Thread-safe for concurrent processing
Transparency
All business logic is:
- Defined in JSON (not compiled code)
- Auditable and version-controllable
- Modifiable without rebuilding
Technology Stack
Core
| Technology | Version | Purpose |
|---|---|---|
| Rust | 1.89+ | Language |
| Tokio | 1.48 | Async runtime |
| Axum | 0.8 | HTTP framework |
| serde_json | 1.0 | JSON processing |
Message Processing
| Library | Purpose |
|---|---|
| swift-mt-message | SWIFT MT parsing |
| mx-message | ISO 20022 parsing |
| quick-xml | XML serialization |
Database & API
| Technology | Purpose |
|---|---|
| MongoDB | Message storage (optional) |
| utoipa | OpenAPI generation |
| async-graphql | GraphQL API |
Open Source Ecosystem
All components are open source under Apache 2.0:
| Project | GitHub | Documentation |
|---|---|---|
| Reframe | GoPlasmatic/Reframe | This site |
| Datalogic | GoPlasmatic/datalogic-rs | Docs |
| Dataflow | GoPlasmatic/dataflow-rs | Docs |
| Datafake | GoPlasmatic/datafake-rs | Docs |
Each project includes an interactive playground for testing.
Performance Characteristics
Latency
| Operation | Typical Latency |
|---|---|
| MT103 → pacs.008 | < 1ms |
| pacs.008 → MT103 | < 1ms |
| Validation | < 0.5ms |
| Sample generation | < 2ms |
Throughput
| Configuration | Messages/Second |
|---|---|
| Single instance (4 CPU) | 5,000+ |
| Horizontal scaling | Linear |
Resource Usage
| Resource | Typical Usage |
|---|---|
| Memory | 256-512 MB |
| CPU | Low (mostly I/O bound) |
| Startup time | < 5 seconds |
Datalogic
The JSONLogic rules engine powering Reframe transformations.
What is Datalogic?
Datalogic is a high-performance Rust implementation of JSONLogic - a standard for expressing business logic as JSON.
In Reframe, Datalogic evaluates all field mappings and business rules during transformation.
Role in Reframe
Transformation Pipeline
│
▼
┌───────────────────┐
│ Field Mapping │
│ { │
│ "path": "...", │
│ "logic": {...} │◄──── Datalogic evaluates this
│ } │
└───────────────────┘
│
▼
Transformed Data
Key Features
59 Built-in Operators
| Category | Examples |
|---|---|
| Comparison | ==, !=, >, <, >=, <= |
| Boolean | and, or, !, !! |
| Arithmetic | +, -, *, /, %, min, max |
| String | cat, substr, in, upper, lower |
| Array | map, filter, reduce, all, some |
| Control | if, ?:, ?? |
| Date/Time | now, format_date, parse_date |
Pre-Compilation
Rules are compiled once at startup:
- No parsing during request processing
- O(1) rule lookup
- Zero-copy execution
Thread-Safe
- Safe concurrent evaluation
- Arc-wrapped compiled rules
- Native async/Tokio support
Example Rules
Direct Mapping
{"var": "data.SwiftMT.fields.20.transaction_reference"}
Conditional Logic
{
"if": [
{"==": [{"var": "data.field"}, "A"]},
"Result A",
"Result B"
]
}
String Operations
{
"cat": [
{"var": "data.first"},
" ",
{"var": "data.last"}
]
}
Complex Transformation
{
"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
"SHAR",
{"if": [
{"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
"DEBT",
"CRED"
]}
]
}
Interactive Playground
Try Datalogic expressions in the browser:
Resources
| Resource | Link |
|---|---|
| Documentation | goplasmatic.github.io/datalogic-rs |
| GitHub | github.com/GoPlasmatic/datalogic-rs |
| Crates.io | crates.io/crates/datalogic-rs |
| Playground | Interactive Playground |
Usage in Reframe
Transformation Rules
{
"path": "data.output.PmtId.InstrId",
"logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
}
Workflow Conditions
{
"id": "mt103-workflow",
"condition": {
"and": [
{"==": [{"var": "metadata.direction"}, "outgoing"]},
{"==": [{"var": "metadata.message_type"}, "MT103"]}
]
}
}
Validation Rules
{
"rules": [
{
"logic": {">": [{"var": "data.amount"}, 0]},
"message": "Amount must be positive"
}
]
}
Dataflow
The workflow orchestration engine powering Reframe pipelines.
What is Dataflow?
Dataflow is an async-first workflow orchestration engine built in Rust. It executes transformation pipelines by routing messages through a series of workflows and tasks.
In Reframe, Dataflow manages the transformation pipeline - determining which workflows execute and in what order.
Role in Reframe
Message Input
│
▼
┌───────────────────────────────────────────────┐
│ Dataflow Engine │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
│ │Workflow │──▶│Workflo w │──▶│Workflow │ │
│ │Priority:1│ │Priority:5│ │Priority:10│ │
│ └──────────┘ └──────────┘ └───────────┘ │
│ │
│ Each workflow contains tasks that: │
│ • Map fields (using Datalogic) │
│ • Validate data │
│ • Call custom functions │
└───────────────────────────────────────────────┘
│
▼
Message Output
Key Features
Priority-Based Execution
Workflows execute in priority order (lowest first):
Priority 1: parse-mt.json
Priority 2: detect-variant.json
Priority 3: bah-mapping.json
Priority 5: document-mapping.json
Priority 10: combine-xml.json
Conditional Routing
Each workflow has a condition that determines if it runs:
{
"condition": {
"and": [
{"==": [{"var": "metadata.direction"}, "outgoing"]},
{"==": [{"var": "metadata.message_type"}, "MT103"]}
]
}
}
Pre-Compiled Workflows
- All JSONLogic compiled at startup
- Zero runtime parsing
- Indexed for O(1) access
Audit Trail
Every change is recorded:
{
"audit_trail": [
{
"timestamp": "2025-01-15T10:30:00Z",
"workflow_id": "mt103-mapping",
"task_id": "map-amount",
"path": "data.output.IntrBkSttlmAmt",
"old_value": null,
"new_value": "50000.00"
}
]
}
Interactive Playground
Try Dataflow workflows in the browser:
Resources
| Resource | Link |
|---|---|
| Documentation | goplasmatic.github.io/dataflow-rs |
| GitHub | github.com/GoPlasmatic/dataflow-rs |
| Crates.io | crates.io/crates/dataflow-rs |
| Playground | Interactive Playground |
Workflow Structure
{
"id": "mt103-document-mapping",
"name": "MT103 Document Mapping",
"priority": 5,
"condition": {
"==": [{"var": "metadata.message_type"}, "MT103"]
},
"tasks": [
{
"id": "map-payment-id",
"function": {
"name": "map",
"input": {
"mappings": [
{
"path": "data.output.PmtId.InstrId",
"logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
}
]
}
}
}
]
}
Task Types
Map Task
Transform data using JSONLogic:
{
"function": {
"name": "map",
"input": {
"mappings": [
{"path": "output.field", "logic": {"var": "input.field"}}
]
}
}
}
Validation Task
Validate data against rules:
{
"function": {
"name": "validation",
"input": {
"rules": [
{"logic": {"!!": {"var": "data.required"}}, "message": "Required field"}
]
}
}
}
Custom Function
Call registered functions:
{
"function": {
"name": "parse_mt",
"input": {"source": "data.raw", "target": "data.parsed"}
}
}
Workflow Orchestration Guide →
Datafake
The test data generation library powering Reframe sample generation.
What is Datafake?
Datafake is a Rust library for generating realistic test data, compatible with the Faker.js API. It provides generators for common data types including financial identifiers.
In Reframe, Datafake generates sample SWIFT MT and ISO 20022 messages for testing.
Role in Reframe
Generate Request
{
"message_type": "MT103",
"scenario": "standard"
}
│
▼
┌─────────────────────────────────────────────┐
│ Datafake Engine │
│ │
│ Generate: │
│ • BIC codes (sender/receiver) │
│ • IBAN accounts │
│ • Currency amounts │
│ • Company names │
│ • Addresses │
│ • Transaction references │
│ • UUIDs (UETR) │
└─────────────────────────────────────────────┘
│
▼
Sample Message
Key Features
Financial Data Generators
| Generator | Example Output |
|---|---|
| BIC | BNPAFRPPXXX |
| IBAN | FR7630006000011234567890189 |
| Currency | USD, EUR, GBP |
| Amount | 50000.00 |
| LEI | 5493001KJTIIGC8Y1R12 |
General Data Generators
| Generator | Example Output |
|---|---|
| Company name | Acme International Inc |
| Address | 123 Main Street, New York NY 10001 |
| Country | US, DE, GB |
| Date | 2025-01-15 |
| UUID | f47ac10b-58cc-4372-a567-0e02b2c3d479 |
Deterministic Output
With seeding, generates reproducible data:
{
"variables": {
"ref": {"fake": ["uuid"]},
"amount": {"fake": ["u64", 1000, 100000]}
},
"seed": 12345
}
Interactive Playground
Try Datafake generators in the browser:
Resources
| Resource | Link |
|---|---|
| Documentation | goplasmatic.github.io/datafake-rs |
| GitHub | github.com/GoPlasmatic/datafake-rs |
| Crates.io | crates.io/crates/datafake-rs |
| Playground | Interactive Playground |
Scenario Configuration
Sample scenarios use Datafake in variable definitions:
{
"description": "MT103 Standard Transfer",
"variables": {
"sender_bic": {"fake": ["bic"]},
"receiver_bic": {"fake": ["bic"]},
"currency": {"fake": ["enum", "USD", "EUR", "GBP"]},
"amount": {"fake": ["u64", 5000, 500000]},
"uetr": {"fake": ["uuid"]},
"sender_name": {"fake": ["company_name"]},
"receiver_name": {"fake": ["company_name"]},
"reference": {"fake": ["alphanumeric", 16]}
},
"schema": {
"basic_header": {
"sender_bic": "{{sender_bic}}"
},
"fields": {
"20": {"transaction_reference": "{{reference}}"},
"32A": {
"currency": "{{currency}}",
"amount": "{{amount}}"
}
}
}
}
Generator Types
String Generators
{"fake": ["alphanumeric", 10]}
{"fake": ["alpha", 5]}
{"fake": ["numeric", 8]}
{"fake": ["uuid"]}
Number Generators
{"fake": ["u64", 1000, 100000]}
{"fake": ["f64", 0.0, 100.0]}
{"fake": ["i32", -100, 100]}
Financial Generators
{"fake": ["bic"]}
{"fake": ["iban", "DE"]}
{"fake": ["currency_code"]}
{"fake": ["lei"]}
Selection Generators
{"fake": ["enum", "USD", "EUR", "GBP", "JPY"]}
{"fake": ["one_of", ["Option A", "Option B", "Option C"]]}
Date Generators
{"fake": ["date_future", 30]}
{"fake": ["date_past", 90]}
{"fake": ["datetime"]}
Message Types Reference
Complete list of supported SWIFT MT and ISO 20022 message types.
SWIFT MT Messages
Customer Payments (MT1xx)
| Type | Name | Description |
|---|---|---|
| MT101 | Request for Transfer | Customer request for multiple transfers |
| MT103 | Single Customer Credit Transfer | Individual payment instruction |
| MT104 | Direct Debit | Direct debit instruction |
| MT107 | General Direct Debit | General direct debit message |
Cheques (MT1xx)
| Type | Name | Description |
|---|---|---|
| MT110 | Advice of Cheque(s) | Notification of cheque collection |
| MT111 | Stop Payment of a Cheque | Request to stop cheque payment |
| MT112 | Status of Request for Stop Payment | Response to stop payment request |
Cancellation & Investigation (MT19x/MT29x)
| Type | Name | Description |
|---|---|---|
| MT192 | Request for Cancellation | Customer payment cancellation request |
| MT196 | Answers | Response to customer inquiries |
| MT199 | Free Format Message | General purpose customer message |
| MT292 | Request for Cancellation | FI payment cancellation request |
| MT296 | Answers | Response to FI inquiries |
| MT299 | Free Format Message for FIs | General purpose FI message |
Financial Institution Transfers (MT2xx)
| Type | Name | Description |
|---|---|---|
| MT200 | Financial Institution Transfer for Own Account | Transfer for bank’s own account |
| MT202 | General Financial Institution Transfer | FI-to-FI transfer |
| MT202COV | Cover Payment | Cover for underlying customer payment |
| MT204 | Direct Debit | Financial institution direct debit |
| MT205 | Financial Institution Transfer Execution | Serial FI transfer |
| MT205COV | Serial Cover Payment | Cover for serial transfers |
| MT210 | Notice to Receive | Notification of incoming payment |
Account Statements & Notifications (MT9xx)
| Type | Name | Description |
|---|---|---|
| MT900 | Confirmation of Debit | Debit confirmation to account owner |
| MT910 | Confirmation of Credit | Credit confirmation to account owner |
| MT920 | Request Message | Account statement request |
| MT935 | Rate Change Advice | Interest rate change notification |
| MT940 | Customer Statement | End-of-day account statement |
| MT941 | Balance Report | Account balance report |
| MT942 | Interim Transaction Report | Intraday transaction report |
| MT950 | Statement Message | FI account statement |
ISO 20022 Messages
Payments Clearing & Settlement (pacs)
| Type | Name | Description |
|---|---|---|
| pacs.002 | FIToFI Payment Status Report | Payment status notification |
| pacs.003 | FIToFI Customer Direct Debit | Direct debit instruction |
| pacs.004 | Payment Return | Return of a payment |
| pacs.008 | FIToFI Customer Credit Transfer | Customer payment instruction |
| pacs.009 | Financial Institution Credit Transfer | FI-to-FI transfer |
| pacs.010 | Financial Institution Direct Debit | FI direct debit |
Payment Initiation (pain)
| Type | Name | Description |
|---|---|---|
| pain.001 | Customer Credit Transfer Initiation | Customer payment request |
| pain.008 | Customer Direct Debit Initiation | Direct debit request |
Cash Management (camt)
| Type | Name | Description |
|---|---|---|
| camt.025 | Receipt | Acknowledgment of receipt |
| camt.029 | Resolution of Investigation | Investigation response |
| camt.052 | Bank to Customer Account Report | Intraday account report |
| camt.053 | Bank to Customer Statement | End-of-day statement |
| camt.054 | Bank to Customer Debit/Credit Notification | Transaction notification |
| camt.056 | FIToFI Payment Cancellation Request | Payment cancellation |
| camt.057 | Notification to Account Owner | Account owner notification |
| camt.058 | Notification to Receive Cancellation | Cancel notification to receive |
| camt.060 | Account Reporting Request | Statement request |
| camt.105 | Charges Payment Notification | Charges notification |
| camt.106 | Request for Payment of Charges | Charges request |
| camt.107 | Cheque Presentment Notification | Cheque notification |
| camt.108 | Cheque Cancellation or Stop Request | Stop cheque |
| camt.109 | Cheque Cancellation or Stop Report | Stop cheque response |
Administration (admi)
| Type | Name | Description |
|---|---|---|
| admi.024 | System Event Notification | System event message |
Error Codes Reference
Complete list of error codes returned by the Reframe API.
Error Response Format
{
"success": false,
"errors": [
{
"error_type": "validation_error",
"code": "INVALID_FORMAT",
"message": "Description of the error",
"field": "field_name",
"location": "Path or location",
"details": { ... }
}
]
}
Error Types
| Type | Description |
|---|---|
parser_error | Message parsing failed |
validation_error | Message failed validation |
business_validation_error | Business rule violation |
transformation_error | Transformation failed |
schema_error | XSD schema violation |
system_error | Internal system error |
Parser Errors
| Code | Description |
|---|---|
MT_PARSE_ERROR | Failed to parse SWIFT MT message |
XML_PARSE_ERROR | Failed to parse XML message |
INVALID_BLOCK_STRUCTURE | Invalid SWIFT block structure |
MISSING_REQUIRED_BLOCK | Required block is missing |
INVALID_HEADER | Invalid message header |
Validation Errors
| Code | Description |
|---|---|
INVALID_FORMAT | Field format is invalid |
INVALID_LENGTH | Field length exceeds limits |
MISSING_REQUIRED_FIELD | Required field is missing |
INVALID_FIELD_VALUE | Field value is not allowed |
INVALID_CHARACTER_SET | Invalid characters in field |
INVALID_DATE_FORMAT | Invalid date or time format |
INVALID_CURRENCY_CODE | Invalid currency code |
INVALID_AMOUNT_FORMAT | Invalid amount format |
INVALID_BIC | Invalid BIC/SWIFT code |
INVALID_IBAN | Invalid IBAN format |
Business Validation Errors
| Code | Description |
|---|---|
NVR_VIOLATION | Network Validation Rule violation |
CBPR_VIOLATION | CBPR+ requirement not met |
CROSS_FIELD_ERROR | Cross-field validation failed |
CONDITIONAL_FIELD_ERROR | Conditional field requirement not met |
DUPLICATE_REFERENCE | Duplicate transaction reference |
INVALID_DATE_RANGE | Date range is invalid |
CURRENCY_MISMATCH | Currency codes don’t match |
Transformation Errors
| Code | Description |
|---|---|
UNSUPPORTED_MESSAGE_TYPE | Message type not supported |
UNSUPPORTED_SCENARIO | Transformation scenario not found |
MAPPING_ERROR | Field mapping failed |
DATA_TRUNCATION | Data was truncated during transformation |
CHARACTER_CONVERSION_ERROR | Character set conversion failed |
TRANSFORMATION_FAILED | General transformation failure |
Schema Errors
| Code | Description |
|---|---|
XSD_VALIDATION_ERROR | XSD schema validation failed |
INVALID_NAMESPACE | Invalid XML namespace |
INVALID_ELEMENT | Unknown or invalid XML element |
MISSING_REQUIRED_ELEMENT | Required XML element missing |
System Errors
| Code | Description |
|---|---|
INTERNAL_ERROR | Internal server error |
TIMEOUT | Operation timed out |
SERVICE_UNAVAILABLE | Service temporarily unavailable |
CONFIGURATION_ERROR | Configuration error |
Glossary
Key terms used in ISO 20022, SWIFT, and CBPR+ messaging.
ISO 20022 Terms
Business Application Header (BAH)
The header element in ISO 20022 messages containing routing and processing information. Includes sender/receiver BICs, message definition identifier, and creation timestamp.
Document
The root element of an ISO 20022 message containing the business payload. Each message type has a specific document structure defined by its XML schema.
Message Definition Identifier
A unique identifier for an ISO 20022 message type, following the pattern area.type.variant.version (e.g., pacs.008.001.12).
Message Type
A standardized ISO 20022 message format. Common types include:
- pacs - Payments Clearing and Settlement
- camt - Cash Management
- pain - Payment Initiation
Schema
The XML Schema Definition (XSD) that defines the structure and validation rules for an ISO 20022 message.
Supplementary Data
Optional extension elements in ISO 20022 messages for carrying additional information not covered by the standard schema.
SWIFT Terms
Application Header
The second block of a SWIFT MT message containing message type, sender/receiver information, and processing details.
Basic Header
The first block of a SWIFT MT message identifying the application, service, and session information.
BIC (Bank Identifier Code)
An 8 or 11 character code that uniquely identifies a financial institution. Also known as SWIFT code.
Field Tag
A two or three character identifier for a data field in SWIFT MT messages (e.g., Tag 20, Tag 32A, Tag 50K).
FIN (Financial Information Network)
SWIFT’s messaging service for financial transaction messages using the MT format.
MT Message
SWIFT Message Type - the legacy text-based format for financial messages (e.g., MT103, MT202).
MX Message
SWIFT’s XML-based message format aligned with ISO 20022 standards.
Trailer Block
The fifth block of a SWIFT MT message containing message authentication and checksum information.
User Header
The third block of a SWIFT MT message containing optional banking priority and delivery information.
CBPR+ Terms
CBPR+ (Cross-Border Payments and Reporting Plus)
SWIFT’s guidelines for implementing ISO 20022 messages in cross-border payments, ensuring interoperability between financial institutions.
Coexistence Period
The transition period (2023-2025) during which both MT and MX message formats are supported for cross-border payments.
Market Practice
Agreed conventions for using ISO 20022 messages in specific contexts, ensuring consistent implementation across institutions.
SR2025 (Standards Release 2025)
SWIFT’s annual standards release for 2025, marking the end of the coexistence period and full transition to ISO 20022.
Translation Rules
The mapping specifications that define how MT message fields correspond to ISO 20022 elements and vice versa.
Usage Guidelines
CBPR+ documentation specifying how ISO 20022 messages should be structured and populated for cross-border payments.
Payment Terms
Charge Bearer
Indicates which party pays the transaction charges:
- SHA (Shared) - Charges shared between parties
- OUR - Sender pays all charges
- BEN - Beneficiary pays all charges
Clearing System
The infrastructure for settling payments between financial institutions (e.g., CHIPS, Fedwire, TARGET2).
Credit Transfer
A payment instruction to move funds from debtor to creditor account.
Debtor
The party whose account is debited in a payment transaction (payer/sender).
Creditor
The party whose account is credited in a payment transaction (payee/beneficiary).
Instructing Agent
The financial institution instructing the next party in the payment chain.
Instructed Agent
The financial institution receiving the payment instruction.
Interbank Settlement Amount
The amount being transferred between financial institutions, excluding charges.
Interbank Settlement Date
The date on which the settlement between banks occurs.
Service Level
Indicates the type of processing for a payment:
- G001 - SWIFT gpi (tracked payments)
- G002 - SWIFT gpi for cover payments
- G003 - SWIFT gpi for financial institution transfers
- G004 - SWIFT gpi for direct debits
Settlement Method
How the payment is settled between banks:
- INDA - Instructed Agent account
- INGA - Instructing Agent account
- COVE - Cover method
- CLRG - Clearing system
UETR (Unique End-to-End Transaction Reference)
A UUID that uniquely identifies a payment throughout its lifecycle, used for gpi tracking.
Technical Terms
Dataflow
Reframe’s workflow orchestration engine that manages transformation pipelines.
Datalogic
Reframe’s JSONLogic implementation for evaluating business rules during transformation.
Datafake
Reframe’s test data generation library for creating sample messages.
Hot Reload
The ability to update transformation rules at runtime without restarting the service.
JSONLogic
A standard for expressing business logic as JSON, enabling portable and auditable rules.
Package
A collection of workflows and rules that define transformations for a specific message standard (e.g., CBPR+).
Pipeline
The sequence of processing stages a message passes through during transformation.
Workflow
A named set of tasks that execute in priority order during message processing.
Identifiers
IBAN (International Bank Account Number)
A standardized international account number format for identifying bank accounts.
LEI (Legal Entity Identifier)
A 20-character alphanumeric code that uniquely identifies legal entities in financial transactions.
MCC (Merchant Category Code)
A four-digit code classifying the type of business or merchant.
National ID
A country-specific identifier for organizations or individuals.
Message Categories
Customer Payments (MT1xx / pacs.008)
Messages for customer credit transfers initiated by corporate customers.
Financial Institution Transfers (MT2xx / pacs.009)
Messages for bank-to-bank transfers not involving customer accounts.
Cash Management (MT9xx / camt.xxx)
Messages for account statements, balance reports, and cash position management.
Securities (MT5xx)
Messages for securities trading, settlement, and custody operations.
Frequently Asked Questions
Common questions about Reframe, the open source SWIFT MT to ISO 20022 transformation engine.
What is Reframe?
Reframe is an open source transformation engine for converting financial messages between formats. It specializes in SWIFT MT to ISO 20022 conversion using auditable JSONLogic rules.
Key features:
- High-performance Rust engine with sub-millisecond latency
- Transparent, auditable transformation rules
- Free CBPR+ package with 41+ scenarios
- Apache 2.0 licensed
Learn more about the architecture →
Is Reframe free to use?
Yes, Reframe is completely free and open source under the Apache 2.0 license. This includes:
- The core Reframe transformation engine
- The CBPR+ package with 41+ transformation scenarios
- All documentation and examples
There are no licensing fees, usage limits, or hidden costs.
What is CBPR+ and does Reframe support it?
CBPR+ (Cross-Border Payments and Reporting Plus) is SWIFT’s framework for migrating from MT messages to ISO 20022.
Reframe includes a free CBPR+ package that supports:
| Transformation | Description |
|---|---|
| MT103 → pacs.008 | Customer credit transfers |
| MT202 → pacs.009 | FI credit transfers |
| MT940 → camt.053 | Account statements |
| + 38 more scenarios | Returns, cancellations, status |
Is Reframe SR2025 compliant?
Yes, the CBPR+ package is fully compliant with SWIFT Standards Release 2025 (SR2025), which becomes mandatory in November 2025.
SR2025 features supported:
- Business Application Header v3
- UETR (Unique End-to-End Transaction Reference)
- Enhanced party identification with LEI
- Structured remittance information
- Latest message versions (pacs.008.001.12, etc.)
Learn about SR2025 compliance →
What message types does Reframe support?
SWIFT MT Messages
MT101, MT103, MT104, MT107, MT110, MT111, MT112, MT192, MT196, MT199, MT202, MT205, MT210, MT292, MT296, MT299, MT900, MT910, MT920, MT935, MT940, MT941, MT942, MT950
ISO 20022 Messages
pacs.002, pacs.003, pacs.008, pacs.009, pain.001, pain.008, camt.025, camt.029, camt.052, camt.053, camt.054, camt.056, camt.057, camt.060
View the complete message catalog →
How do I get started with Reframe?
Get started in under 5 minutes using Docker:
# Pull and run Reframe
docker run -d -p 3000:3000 plasmatic/reframe:latest
# Test the API
curl http://localhost:3000/health
Or try the interactive playground without any installation:
What makes Reframe different from other transformation tools?
| Feature | Reframe | Proprietary Solutions |
|---|---|---|
| Rules | Auditable JSONLogic | Black-box logic |
| License | Apache 2.0 (Free) | Expensive licensing |
| Performance | Sub-millisecond (Rust) | Slower (JVM) |
| Updates | Hot-reload rules | Vendor intervention |
| Customization | Full access to rules | Limited or none |
Learn about the open source advantage →
Can I use Reframe in production?
Yes, Reframe is production-ready with:
- Health checks - Monitor service status
- Hot-reload - Update rules without downtime
- Kubernetes support - Enterprise deployment
- High performance - Thousands of messages/second
- Audit trails - Full transformation logging
Where can I get help?
- Documentation: You’re reading it!
- GitHub Issues: Report bugs or request features
- GitHub Discussions: Ask questions
Related Resources
- Quick Start Guide - Get running in 5 minutes
- Interactive Playground - Try transformations online
- API Reference - Complete API documentation
- CBPR+ Package Guide - SWIFT MT ↔ ISO 20022